""" Quick 5-Trial Test with Real NX Solves Tests the complete optimization pipeline with hooks and logging. """ from pathlib import Path import sys from datetime import datetime # Add project root to path so we can import atomizer_paths sys.path.insert(0, str(Path(__file__).parent.parent)) # Use intelligent path resolution import atomizer_paths atomizer_paths.ensure_imports() from optimization_engine.core.runner import OptimizationRunner from optimization_engine.nx.solver import run_nx_simulation from optimization_engine.result_extractors.extractors import ( stress_extractor, displacement_extractor ) # Global variable to store current design variables _current_design_vars = {} def bracket_model_updater(design_vars: dict): """Store design variables for the simulation runner.""" global _current_design_vars _current_design_vars = design_vars.copy() print(f"\n[MODEL UPDATE] Design variables prepared") for name, value in design_vars.items(): print(f" {name} = {value:.4f}") def bracket_simulation_runner() -> Path: """Run NX solver via journal on running NX GUI session.""" global _current_design_vars sim_file = atomizer_paths.studies() / "bracket_stress_minimization/model/Bracket_sim1.sim" print("\n[SIMULATION] Running via journal on NX GUI...") print(f" SIM file: {sim_file.name}") if _current_design_vars: print(f" Expression updates: {_current_design_vars}") try: op2_file = run_nx_simulation( sim_file=sim_file, nastran_version="2412", timeout=300, cleanup=True, use_journal=True, expression_updates=_current_design_vars ) print(f"[SIMULATION] Complete! Results: {op2_file.name}") return op2_file except Exception as e: print(f"[SIMULATION] FAILED: {e}") raise if __name__ == "__main__": print("="*60) print("5-TRIAL REAL OPTIMIZATION TEST WITH LOGGING") print("="*60) print("\nThis will:") print("- Run 5 real NX solves (not dummy data)") print("- Create detailed log files in optimization_logs/") print("- Test all hooks (pre_solve, post_solve, post_extraction)") print("- Verify design variables actually change results") print("\nTime: ~3-5 minutes") print("="*60) input("\nPress ENTER to continue (Ctrl+C to cancel)...") config_path = atomizer_paths.studies() / "bracket_stress_minimization/optimization_config_stress_displacement.json" runner = OptimizationRunner( config_path=config_path, model_updater=bracket_model_updater, simulation_runner=bracket_simulation_runner, result_extractors={ 'stress_extractor': stress_extractor, 'displacement_extractor': displacement_extractor } ) # Generate unique study name with timestamp study_name = f"test_5trials_{datetime.now().strftime('%Y%m%d_%H%M%S')}" print("\n" + "="*60) print("RUNNING 5-TRIAL OPTIMIZATION") print("="*60) print(f"Study name: {study_name}") print("="*60) try: study = runner.run( study_name=study_name, n_trials=5, resume=False ) print("\n" + "="*60) print("OPTIMIZATION COMPLETE!") print("="*60) print(f"\nBest stress: {study.best_value:.2f} MPa") print(f"\nBest parameters:") for param, value in study.best_params.items(): print(f" {param}: {value:.4f}") # Show log files created log_dir = runner.output_dir / "trial_logs" if log_dir.exists(): log_files = sorted(log_dir.glob("trial_*.log")) print(f"\n{len(log_files)} detailed trial logs created:") print(f" {log_dir}") print("\nExample log file (open to see detailed iteration trace):") if log_files: print(f" {log_files[0].name}") print(f"\nResults also saved to: {runner.output_dir}") except Exception as e: print(f"\n{'='*60}") print("ERROR DURING OPTIMIZATION") print("="*60) print(f"{e}") import traceback traceback.print_exc() sys.exit(1)