feat: Implement Phase 1 - Plugin & Hook System
Core plugin architecture for LLM-driven optimization: New Features: - Hook system with 6 lifecycle points (pre_mesh, post_mesh, pre_solve, post_solve, post_extraction, custom_objectives) - HookManager for centralized registration and execution - Code validation with AST-based safety checks - Feature registry (JSON) for LLM capability discovery - Example plugin: log_trial_start - 23 comprehensive tests (all passing) Integration: - OptimizationRunner now loads plugins automatically - Hooks execute at 5 points in optimization loop - Custom objectives can override total_objective via hooks Safety: - Module whitelist (numpy, scipy, pandas, optuna, pyNastran) - Dangerous operation blocking (eval, exec, os.system, subprocess) - Optional file operation permission flag Files Added: - optimization_engine/plugins/__init__.py - optimization_engine/plugins/hooks.py - optimization_engine/plugins/hook_manager.py - optimization_engine/plugins/validators.py - optimization_engine/feature_registry.json - optimization_engine/plugins/pre_solve/log_trial_start.py - tests/test_plugin_system.py (23 tests) Files Modified: - optimization_engine/runner.py (added hook integration) Ready for Phase 2: LLM interface layer 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
243
optimization_engine/feature_registry.json
Normal file
243
optimization_engine/feature_registry.json
Normal file
@@ -0,0 +1,243 @@
|
||||
{
|
||||
"version": "1.0.0",
|
||||
"last_updated": "2025-01-15",
|
||||
"description": "Registry of all Atomizer capabilities for LLM discovery and usage",
|
||||
|
||||
"core_features": {
|
||||
"optimization": {
|
||||
"description": "Core optimization engine using Optuna",
|
||||
"module": "optimization_engine.runner",
|
||||
"capabilities": [
|
||||
"Multi-objective optimization with weighted sum",
|
||||
"TPE (Tree-structured Parzen Estimator) sampler",
|
||||
"CMA-ES sampler",
|
||||
"Gaussian Process sampler",
|
||||
"50-trial default with 20 startup trials",
|
||||
"Automatic checkpoint and resume",
|
||||
"SQLite-based study persistence"
|
||||
],
|
||||
"usage": "python examples/test_journal_optimization.py",
|
||||
"llm_hint": "Use this for Bayesian optimization with NX simulations"
|
||||
},
|
||||
|
||||
"nx_integration": {
|
||||
"description": "Siemens NX simulation automation via journal scripts",
|
||||
"module": "optimization_engine.nx_solver",
|
||||
"capabilities": [
|
||||
"Update CAD expressions via NXOpen",
|
||||
"Execute NX Nastran solver",
|
||||
"Extract OP2 results (stress, displacement)",
|
||||
"Extract mass properties",
|
||||
"Precision control (4 decimals for mm/degrees/MPa)"
|
||||
],
|
||||
"usage": "from optimization_engine.nx_solver import run_nx_simulation",
|
||||
"llm_hint": "Use for running FEA simulations and extracting results"
|
||||
},
|
||||
|
||||
"result_extraction": {
|
||||
"description": "Extract metrics from simulation results",
|
||||
"module": "optimization_engine.result_extractors",
|
||||
"extractors": {
|
||||
"stress_extractor": {
|
||||
"description": "Extract stress data from OP2 files",
|
||||
"metrics": ["max_von_mises", "mean_von_mises", "max_principal"],
|
||||
"file_type": "OP2",
|
||||
"usage": "Returns stress in MPa"
|
||||
},
|
||||
"displacement_extractor": {
|
||||
"description": "Extract displacement data from OP2 files",
|
||||
"metrics": ["max_displacement", "mean_displacement"],
|
||||
"file_type": "OP2",
|
||||
"usage": "Returns displacement in mm"
|
||||
},
|
||||
"mass_extractor": {
|
||||
"description": "Extract mass properties",
|
||||
"metrics": ["total_mass", "center_of_gravity"],
|
||||
"file_type": "NX Part",
|
||||
"usage": "Returns mass in kg"
|
||||
}
|
||||
},
|
||||
"llm_hint": "Use extractors to define objectives and constraints"
|
||||
}
|
||||
},
|
||||
|
||||
"plugin_system": {
|
||||
"description": "Extensible hook system for custom functionality",
|
||||
"module": "optimization_engine.plugins",
|
||||
"version": "1.0.0",
|
||||
|
||||
"hook_points": {
|
||||
"pre_mesh": {
|
||||
"description": "Execute before meshing operations",
|
||||
"context": ["trial_number", "design_variables", "sim_file", "working_dir"],
|
||||
"use_cases": [
|
||||
"Modify geometry based on parameters",
|
||||
"Set up boundary conditions",
|
||||
"Configure mesh settings"
|
||||
]
|
||||
},
|
||||
"post_mesh": {
|
||||
"description": "Execute after meshing, before solve",
|
||||
"context": ["trial_number", "mesh_info", "element_count", "node_count"],
|
||||
"use_cases": [
|
||||
"Validate mesh quality",
|
||||
"Export mesh for visualization",
|
||||
"Log mesh statistics"
|
||||
]
|
||||
},
|
||||
"pre_solve": {
|
||||
"description": "Execute before solver launch",
|
||||
"context": ["trial_number", "design_variables", "solver_settings"],
|
||||
"use_cases": [
|
||||
"Log trial parameters",
|
||||
"Modify solver settings",
|
||||
"Set up custom load cases"
|
||||
]
|
||||
},
|
||||
"post_solve": {
|
||||
"description": "Execute after solve, before result extraction",
|
||||
"context": ["trial_number", "solve_status", "output_files"],
|
||||
"use_cases": [
|
||||
"Check solver convergence",
|
||||
"Post-process results",
|
||||
"Generate visualizations"
|
||||
]
|
||||
},
|
||||
"post_extraction": {
|
||||
"description": "Execute after result extraction",
|
||||
"context": ["trial_number", "extracted_results", "objectives", "constraints"],
|
||||
"use_cases": [
|
||||
"Calculate custom metrics",
|
||||
"Combine multiple objectives (RSS)",
|
||||
"Apply penalty functions"
|
||||
]
|
||||
},
|
||||
"custom_objective": {
|
||||
"description": "Define custom objective functions",
|
||||
"context": ["extracted_results", "design_variables"],
|
||||
"use_cases": [
|
||||
"RSS of stress and displacement",
|
||||
"Weighted multi-criteria",
|
||||
"Conditional objectives"
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
"api": {
|
||||
"register_hook": {
|
||||
"description": "Register a new hook function",
|
||||
"signature": "hook_manager.register_hook(hook_point, function, description, name=None, priority=100)",
|
||||
"parameters": {
|
||||
"hook_point": "One of: pre_mesh, post_mesh, pre_solve, post_solve, post_extraction, custom_objective",
|
||||
"function": "Callable[[Dict[str, Any]], Optional[Dict[str, Any]]]",
|
||||
"description": "Human-readable description",
|
||||
"priority": "Execution order (lower = earlier)"
|
||||
},
|
||||
"example": "See optimization_engine/plugins/pre_solve/log_trial_start.py"
|
||||
},
|
||||
"execute_hooks": {
|
||||
"description": "Execute all hooks at a specific point",
|
||||
"signature": "hook_manager.execute_hooks(hook_point, context, fail_fast=False)",
|
||||
"returns": "List of hook results"
|
||||
}
|
||||
},
|
||||
|
||||
"validators": {
|
||||
"validate_plugin_code": {
|
||||
"description": "Validate plugin code for safety",
|
||||
"checks": [
|
||||
"Syntax errors",
|
||||
"Dangerous imports (os.system, subprocess, etc.)",
|
||||
"File operations (optional allow)",
|
||||
"Function signature correctness"
|
||||
],
|
||||
"safe_modules": ["math", "numpy", "scipy", "pandas", "pathlib", "json", "optuna", "pyNastran"],
|
||||
"llm_hint": "Always validate LLM-generated code before execution"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"design_variables": {
|
||||
"description": "Parametric CAD variables to optimize",
|
||||
"schema": {
|
||||
"name": "Unique identifier",
|
||||
"expression_name": "NX expression name",
|
||||
"min": "Lower bound (float)",
|
||||
"max": "Upper bound (float)",
|
||||
"units": "Unit system (mm, degrees, etc.)"
|
||||
},
|
||||
"example": {
|
||||
"name": "wall_thickness",
|
||||
"expression_name": "wall_thickness",
|
||||
"min": 3.0,
|
||||
"max": 8.0,
|
||||
"units": "mm"
|
||||
}
|
||||
},
|
||||
|
||||
"objectives": {
|
||||
"description": "Metrics to minimize or maximize",
|
||||
"schema": {
|
||||
"name": "Unique identifier",
|
||||
"extractor": "Result extractor to use",
|
||||
"metric": "Specific metric from extractor",
|
||||
"direction": "minimize or maximize",
|
||||
"weight": "Importance (for multi-objective)",
|
||||
"units": "Unit system"
|
||||
},
|
||||
"example": {
|
||||
"name": "max_stress",
|
||||
"extractor": "stress_extractor",
|
||||
"metric": "max_von_mises",
|
||||
"direction": "minimize",
|
||||
"weight": 1.0,
|
||||
"units": "MPa"
|
||||
}
|
||||
},
|
||||
|
||||
"constraints": {
|
||||
"description": "Limits on simulation outputs",
|
||||
"schema": {
|
||||
"name": "Unique identifier",
|
||||
"extractor": "Result extractor to use",
|
||||
"metric": "Specific metric",
|
||||
"type": "upper_bound or lower_bound",
|
||||
"limit": "Constraint value",
|
||||
"units": "Unit system"
|
||||
},
|
||||
"example": {
|
||||
"name": "max_displacement_limit",
|
||||
"extractor": "displacement_extractor",
|
||||
"metric": "max_displacement",
|
||||
"type": "upper_bound",
|
||||
"limit": 1.0,
|
||||
"units": "mm"
|
||||
}
|
||||
},
|
||||
|
||||
"examples": {
|
||||
"bracket_optimization": {
|
||||
"description": "Minimize stress on a bracket by varying wall thickness",
|
||||
"location": "examples/bracket/",
|
||||
"design_variables": ["wall_thickness"],
|
||||
"objectives": ["max_von_mises"],
|
||||
"trials": 50,
|
||||
"typical_runtime": "2-3 hours",
|
||||
"llm_hint": "Good template for single-objective structural optimization"
|
||||
}
|
||||
},
|
||||
|
||||
"llm_guidelines": {
|
||||
"code_generation": {
|
||||
"hook_template": "Always include: function signature with context dict, docstring, return dict",
|
||||
"validation": "Use validate_plugin_code() before registration",
|
||||
"error_handling": "Wrap in try-except, log errors, return None on failure"
|
||||
},
|
||||
"natural_language_mapping": {
|
||||
"minimize stress": "objective with direction='minimize', extractor='stress_extractor'",
|
||||
"vary thickness 3-8mm": "design_variable with min=3.0, max=8.0, units='mm'",
|
||||
"displacement < 1mm": "constraint with type='upper_bound', limit=1.0",
|
||||
"RSS of stress and displacement": "custom_objective hook with sqrt(stress² + displacement²)"
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user