295 lines
6.7 KiB
Markdown
295 lines
6.7 KiB
Markdown
|
|
# NX Solver Integration Guide
|
||
|
|
|
||
|
|
## Overview
|
||
|
|
|
||
|
|
The NX solver integration allows Atomizer to automatically run Siemens NX Nastran simulations in batch mode during optimization loops.
|
||
|
|
|
||
|
|
## Architecture
|
||
|
|
|
||
|
|
```
|
||
|
|
Optimization Loop:
|
||
|
|
1. Update parameters in .prt file → nx_updater.py
|
||
|
|
2. Run NX solver in batch mode → nx_solver.py ← NEW!
|
||
|
|
3. Extract results from OP2 → op2_extractor_example.py
|
||
|
|
4. Evaluate objectives/constraints → runner.py
|
||
|
|
5. Optuna suggests next parameters → repeat
|
||
|
|
```
|
||
|
|
|
||
|
|
## Quick Start
|
||
|
|
|
||
|
|
### Test 1: Verify Solver Integration
|
||
|
|
|
||
|
|
```bash
|
||
|
|
conda activate test_env
|
||
|
|
python examples/test_nx_solver.py
|
||
|
|
```
|
||
|
|
|
||
|
|
This tests:
|
||
|
|
- NX installation detection
|
||
|
|
- Batch solver execution
|
||
|
|
- OP2 file generation
|
||
|
|
- Error handling
|
||
|
|
|
||
|
|
**Expected**: Solver runs and produces .op2 file in ~1-2 minutes
|
||
|
|
|
||
|
|
### Test 2: Run Optimization with Real Solver
|
||
|
|
|
||
|
|
```bash
|
||
|
|
conda activate test_env
|
||
|
|
python examples/test_optimization_with_solver.py
|
||
|
|
```
|
||
|
|
|
||
|
|
This runs 3 optimization trials with REAL simulations!
|
||
|
|
|
||
|
|
**Expected time**: ~5-10 minutes (depends on model complexity)
|
||
|
|
|
||
|
|
## Usage in Your Code
|
||
|
|
|
||
|
|
### Simple Usage (Convenience Function)
|
||
|
|
|
||
|
|
```python
|
||
|
|
from optimization_engine.nx_solver import run_nx_simulation
|
||
|
|
from pathlib import Path
|
||
|
|
|
||
|
|
sim_file = Path("path/to/model.sim")
|
||
|
|
op2_file = run_nx_simulation(
|
||
|
|
sim_file=sim_file,
|
||
|
|
nastran_version="2412",
|
||
|
|
timeout=600, # 10 minutes
|
||
|
|
cleanup=True # Remove temp files
|
||
|
|
)
|
||
|
|
|
||
|
|
# op2_file now contains path to results
|
||
|
|
```
|
||
|
|
|
||
|
|
### Advanced Usage (Full Control)
|
||
|
|
|
||
|
|
```python
|
||
|
|
from optimization_engine.nx_solver import NXSolver
|
||
|
|
|
||
|
|
solver = NXSolver(
|
||
|
|
nastran_version="2412",
|
||
|
|
timeout=600
|
||
|
|
)
|
||
|
|
|
||
|
|
result = solver.run_simulation(
|
||
|
|
sim_file=sim_file,
|
||
|
|
working_dir=None, # Defaults to sim file directory
|
||
|
|
cleanup=True
|
||
|
|
)
|
||
|
|
|
||
|
|
if result['success']:
|
||
|
|
print(f"OP2: {result['op2_file']}")
|
||
|
|
print(f"Time: {result['elapsed_time']:.1f}s")
|
||
|
|
else:
|
||
|
|
print(f"Errors: {result['errors']}")
|
||
|
|
```
|
||
|
|
|
||
|
|
### Integration with Optimization Runner
|
||
|
|
|
||
|
|
```python
|
||
|
|
from optimization_engine.nx_solver import run_nx_simulation
|
||
|
|
|
||
|
|
def my_simulation_runner() -> Path:
|
||
|
|
"""Simulation runner for optimization."""
|
||
|
|
sim_file = Path("my_model.sim")
|
||
|
|
|
||
|
|
# Run solver
|
||
|
|
op2_file = run_nx_simulation(
|
||
|
|
sim_file=sim_file,
|
||
|
|
nastran_version="2412",
|
||
|
|
timeout=600,
|
||
|
|
cleanup=True
|
||
|
|
)
|
||
|
|
|
||
|
|
return op2_file
|
||
|
|
|
||
|
|
# Use in OptimizationRunner
|
||
|
|
runner = OptimizationRunner(
|
||
|
|
config_path=config_path,
|
||
|
|
model_updater=my_model_updater,
|
||
|
|
simulation_runner=my_simulation_runner, # Uses real solver!
|
||
|
|
result_extractors=extractors
|
||
|
|
)
|
||
|
|
```
|
||
|
|
|
||
|
|
## Configuration
|
||
|
|
|
||
|
|
### Auto-Detection
|
||
|
|
|
||
|
|
By default, NXSolver auto-detects NX installation:
|
||
|
|
|
||
|
|
```python
|
||
|
|
solver = NXSolver(nastran_version="2412")
|
||
|
|
# Searches:
|
||
|
|
# - C:/Program Files/Siemens/NX2412
|
||
|
|
# - C:/Program Files/Siemens/Simcenter3D_2412
|
||
|
|
# - C:/Program Files (x86)/Siemens/NX2412
|
||
|
|
```
|
||
|
|
|
||
|
|
### Manual Configuration
|
||
|
|
|
||
|
|
```python
|
||
|
|
from pathlib import Path
|
||
|
|
|
||
|
|
solver = NXSolver(
|
||
|
|
nx_install_dir=Path("C:/Program Files/Siemens/NX2412"),
|
||
|
|
nastran_version="2412",
|
||
|
|
timeout=1200 # 20 minutes
|
||
|
|
)
|
||
|
|
```
|
||
|
|
|
||
|
|
## Solver Output Files
|
||
|
|
|
||
|
|
### Files Created
|
||
|
|
- `model.op2` - Binary results (kept)
|
||
|
|
- `model.f06` - Text output (kept)
|
||
|
|
- `model.log` - Solver log (kept)
|
||
|
|
- `model.f04` - Intermediate (cleaned up)
|
||
|
|
- `model.dat` - Intermediate (cleaned up)
|
||
|
|
- `model.diag` - Diagnostic (cleaned up)
|
||
|
|
|
||
|
|
### Cleanup Behavior
|
||
|
|
|
||
|
|
With `cleanup=True` (recommended):
|
||
|
|
- Keeps: .op2, .f06, .log
|
||
|
|
- Removes: .f04, .dat, .diag, .master, .dball, plots
|
||
|
|
|
||
|
|
With `cleanup=False`:
|
||
|
|
- Keeps all files for debugging
|
||
|
|
|
||
|
|
## Error Handling
|
||
|
|
|
||
|
|
### Common Issues
|
||
|
|
|
||
|
|
**Issue**: `FileNotFoundError: NX Nastran solver not found`
|
||
|
|
|
||
|
|
**Solution**:
|
||
|
|
- Check NX is installed at standard location
|
||
|
|
- Specify `nx_install_dir` manually
|
||
|
|
- Verify nastran.exe exists in NXNASTRAN/bin/
|
||
|
|
|
||
|
|
**Issue**: `RuntimeError: NX simulation failed`
|
||
|
|
|
||
|
|
**Solution**:
|
||
|
|
- Check .f06 file for error messages
|
||
|
|
- Verify .sim file is valid
|
||
|
|
- Check NX license is available
|
||
|
|
- Ensure model can solve in NX GUI first
|
||
|
|
|
||
|
|
**Issue**: `TimeoutExpired`
|
||
|
|
|
||
|
|
**Solution**:
|
||
|
|
- Increase `timeout` parameter
|
||
|
|
- Simplify model (fewer elements, linear analysis)
|
||
|
|
- Check solver isn't stuck (memory issues)
|
||
|
|
|
||
|
|
### Checking Solver Success
|
||
|
|
|
||
|
|
The solver checks for completion by:
|
||
|
|
1. Looking for "NORMAL TERMINATION" in .f06
|
||
|
|
2. Checking for "FATAL MESSAGE" errors
|
||
|
|
3. Verifying .op2 file was created recently
|
||
|
|
|
||
|
|
## Performance Tips
|
||
|
|
|
||
|
|
### Speed Up Optimization
|
||
|
|
|
||
|
|
1. **Reduce Model Complexity**
|
||
|
|
- Use coarser mesh for initial exploration
|
||
|
|
- Simplify geometry in non-critical areas
|
||
|
|
- Use linear analysis if possible
|
||
|
|
|
||
|
|
2. **Parallel Trials (Future)**
|
||
|
|
- Run multiple trials simultaneously
|
||
|
|
- Requires separate working directories
|
||
|
|
- Use Optuna's parallelization features
|
||
|
|
|
||
|
|
3. **Smart Sampling**
|
||
|
|
- Use TPE sampler (default) for efficiency
|
||
|
|
- Increase `n_startup_trials` for better initial sampling
|
||
|
|
- Use constraints to avoid infeasible regions
|
||
|
|
|
||
|
|
4. **Cleanup Strategy**
|
||
|
|
- Use `cleanup=True` to save disk space
|
||
|
|
- Only keep .op2 and .log files
|
||
|
|
- Archive results after optimization
|
||
|
|
|
||
|
|
### Typical Solve Times
|
||
|
|
|
||
|
|
| Model Size | Analysis Type | Time per Trial |
|
||
|
|
|------------|---------------|----------------|
|
||
|
|
| Small (<10k nodes) | Linear Static | 30-60s |
|
||
|
|
| Medium (10-50k) | Linear Static | 1-3 min |
|
||
|
|
| Large (>50k) | Linear Static | 3-10 min |
|
||
|
|
| Any | Nonlinear | 5-30 min |
|
||
|
|
|
||
|
|
## Batch Processing
|
||
|
|
|
||
|
|
For running many optimizations:
|
||
|
|
|
||
|
|
```python
|
||
|
|
# Save solver instance to reuse
|
||
|
|
solver = NXSolver(nastran_version="2412", timeout=600)
|
||
|
|
|
||
|
|
for trial_params in parameter_sets:
|
||
|
|
# Update model
|
||
|
|
update_nx_model(prt_file, trial_params)
|
||
|
|
|
||
|
|
# Solve
|
||
|
|
result = solver.run_simulation(sim_file, cleanup=True)
|
||
|
|
|
||
|
|
if result['success']:
|
||
|
|
# Extract and analyze
|
||
|
|
results = extract_all_results(result['op2_file'])
|
||
|
|
```
|
||
|
|
|
||
|
|
## Troubleshooting
|
||
|
|
|
||
|
|
### Enable Debug Output
|
||
|
|
|
||
|
|
```python
|
||
|
|
solver = NXSolver(nastran_version="2412")
|
||
|
|
|
||
|
|
result = solver.run_simulation(
|
||
|
|
sim_file=sim_file,
|
||
|
|
cleanup=False # Keep all files
|
||
|
|
)
|
||
|
|
|
||
|
|
# Check detailed output
|
||
|
|
print(result['errors'])
|
||
|
|
|
||
|
|
# Manually inspect files
|
||
|
|
# - Check .f06 for solver messages
|
||
|
|
# - Check .log for execution details
|
||
|
|
# - Check .f04 for input deck
|
||
|
|
```
|
||
|
|
|
||
|
|
### Verify NX Installation
|
||
|
|
|
||
|
|
```python
|
||
|
|
from optimization_engine.nx_solver import NXSolver
|
||
|
|
|
||
|
|
solver = NXSolver(nastran_version="2412")
|
||
|
|
print(f"NX Dir: {solver.nx_install_dir}")
|
||
|
|
print(f"Solver: {solver.solver_exe}")
|
||
|
|
print(f"Exists: {solver.solver_exe.exists()}")
|
||
|
|
```
|
||
|
|
|
||
|
|
## Next Steps
|
||
|
|
|
||
|
|
1. **Test solver integration**: Run `test_nx_solver.py`
|
||
|
|
2. **Test optimization loop**: Run `test_optimization_with_solver.py`
|
||
|
|
3. **Customize for your model**: Modify simulation_runner function
|
||
|
|
4. **Run real optimization**: Increase n_trials to 50-150
|
||
|
|
5. **Analyze results**: Use history.csv to understand parameter sensitivity
|
||
|
|
|
||
|
|
## Support
|
||
|
|
|
||
|
|
For issues:
|
||
|
|
1. Check this guide
|
||
|
|
2. Verify NX installation
|
||
|
|
3. Test .sim file in NX GUI first
|
||
|
|
4. Check solver logs (.f06, .log files)
|
||
|
|
5. Review error messages in result['errors']
|