feat: Major update with validators, skills, dashboard, and docs reorganization

- Add validation framework (config, model, results, study validators)
- Add Claude Code skills (create-study, run-optimization, generate-report,
  troubleshoot, analyze-model)
- Add Atomizer Dashboard (React frontend + FastAPI backend)
- Reorganize docs into structured directories (00-09)
- Add neural surrogate modules and training infrastructure
- Add multi-objective optimization support

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-25 19:23:58 -05:00
parent 74a92803b7
commit e3bdb08a22
155 changed files with 52729 additions and 37 deletions

View File

@@ -24,6 +24,7 @@ from datetime import datetime
import pickle
from optimization_engine.plugins import HookManager
from optimization_engine.training_data_exporter import create_exporter_from_config
class OptimizationRunner:
@@ -79,6 +80,11 @@ class OptimizationRunner:
if summary['total_hooks'] > 0:
print(f"Loaded {summary['enabled_hooks']}/{summary['total_hooks']} plugins")
# Initialize training data exporter (if enabled in config)
self.training_data_exporter = create_exporter_from_config(self.config)
if self.training_data_exporter:
print(f"Training data export enabled: {self.training_data_exporter.export_dir}")
def _load_config(self) -> Dict[str, Any]:
"""Load and validate optimization configuration."""
with open(self.config_path, 'r') as f:
@@ -436,6 +442,32 @@ class OptimizationRunner:
}
self.hook_manager.execute_hooks('post_extraction', post_extraction_context, fail_fast=False)
# Export training data (if enabled)
if self.training_data_exporter:
# Determine .dat and .op2 file paths from result_path
# NX naming: sim_name-solution_N.dat and sim_name-solution_N.op2
if result_path:
sim_dir = Path(result_path).parent if Path(result_path).is_file() else Path(result_path)
sim_name = self.config.get('sim_file', '').replace('.sim', '')
# Try to find the .dat and .op2 files
# Typically: sim_name-solution_1.dat and sim_name-solution_1.op2
dat_files = list(sim_dir.glob(f"{Path(sim_name).stem}*.dat"))
op2_files = list(sim_dir.glob(f"{Path(sim_name).stem}*.op2"))
if dat_files and op2_files:
simulation_files = {
'dat_file': dat_files[0], # Use first match
'op2_file': op2_files[0]
}
self.training_data_exporter.export_trial(
trial_number=trial.number,
design_variables=design_vars,
results=extracted_results,
simulation_files=simulation_files
)
# 5. Evaluate constraints
for const in self.config.get('constraints', []):
value = extracted_results[const['name']]
@@ -614,6 +646,11 @@ class OptimizationRunner:
self._save_study_metadata(study_name)
self._save_final_results()
# Finalize training data export (if enabled)
if self.training_data_exporter:
self.training_data_exporter.finalize()
print(f"Training data export finalized: {self.training_data_exporter.trial_count} trials exported")
# Post-processing: Visualization and Model Cleanup
self._run_post_processing()