docs: Update protocol docs and method selector improvements
- SYS_12: Add extractor library updates - SYS_15: Add method selector documentation updates - method_selector.py: Minor improvements to method selection logic 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -371,9 +371,33 @@ If needed physics isn't in library:
|
|||||||
|---------|-------|----------|
|
|---------|-------|----------|
|
||||||
| "No displacement data found" | Wrong subcase number | Check subcase in OP2 |
|
| "No displacement data found" | Wrong subcase number | Check subcase in OP2 |
|
||||||
| "OP2 file not found" | Solve failed | Check NX logs |
|
| "OP2 file not found" | Solve failed | Check NX logs |
|
||||||
| "Element type not supported" | Using unsupported element | Check available types in function |
|
| "Unknown element type: auto" | Element type not specified | Specify `element_type='cquad4'` or `'ctetra'` |
|
||||||
|
| "No stress results in OP2" | Wrong element type specified | Use correct type for your mesh |
|
||||||
| Import error | Module not exported | Check `__init__.py` exports |
|
| Import error | Module not exported | Check `__init__.py` exports |
|
||||||
|
|
||||||
|
### Element Type Selection Guide
|
||||||
|
|
||||||
|
**Critical**: You must specify the correct element type for stress extraction based on your mesh:
|
||||||
|
|
||||||
|
| Mesh Type | Elements | `element_type=` |
|
||||||
|
|-----------|----------|-----------------|
|
||||||
|
| **Shell** (thin structures) | CQUAD4, CTRIA3 | `'cquad4'` or `'ctria3'` |
|
||||||
|
| **Solid** (3D volumes) | CTETRA, CHEXA | `'ctetra'` or `'chexa'` |
|
||||||
|
|
||||||
|
**How to check your mesh type:**
|
||||||
|
1. Open .dat/.bdf file
|
||||||
|
2. Search for element cards (CQUAD4, CTETRA, etc.)
|
||||||
|
3. Use the dominant element type
|
||||||
|
|
||||||
|
**Common models:**
|
||||||
|
- **Bracket (solid)**: Uses CTETRA → `element_type='ctetra'`
|
||||||
|
- **Beam (shell)**: Uses CQUAD4 → `element_type='cquad4'`
|
||||||
|
- **Mirror (shell)**: Uses CQUAD4 → `element_type='cquad4'`
|
||||||
|
|
||||||
|
**Von Mises column mapping** (handled automatically):
|
||||||
|
- Shell elements (8 columns): von Mises at column 7
|
||||||
|
- Solid elements (10 columns): von Mises at column 9
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Cross-References
|
## Cross-References
|
||||||
@@ -583,3 +607,4 @@ nx_journals/
|
|||||||
| 1.0 | 2025-12-05 | Initial consolidation from scattered docs |
|
| 1.0 | 2025-12-05 | Initial consolidation from scattered docs |
|
||||||
| 1.1 | 2025-12-06 | Added Phase 2: E12 (principal stress), E13 (strain energy), E14 (SPC forces) |
|
| 1.1 | 2025-12-06 | Added Phase 2: E12 (principal stress), E13 (strain energy), E14 (SPC forces) |
|
||||||
| 1.2 | 2025-12-06 | Added Phase 3: E15-E17 (thermal), E18 (modal mass) |
|
| 1.2 | 2025-12-06 | Added Phase 3: E15-E17 (thermal), E18 (modal mass) |
|
||||||
|
| 1.3 | 2025-12-07 | Added Element Type Selection Guide; documented shell vs solid stress columns |
|
||||||
|
|||||||
@@ -385,6 +385,25 @@ if user_confirms:
|
|||||||
| PURE_FEA recommended | High dimensionality | Consider dimension reduction |
|
| PURE_FEA recommended | High dimensionality | Consider dimension reduction |
|
||||||
| GNN_FIELD recommended | Need field visualization | Set up atomizer-field |
|
| GNN_FIELD recommended | Need field visualization | Set up atomizer-field |
|
||||||
|
|
||||||
|
### Config Format Compatibility
|
||||||
|
|
||||||
|
The method selector supports multiple config JSON formats:
|
||||||
|
|
||||||
|
| Old Format | New Format | Both Supported |
|
||||||
|
|------------|------------|----------------|
|
||||||
|
| `parameter` | `name` | Variable name |
|
||||||
|
| `bounds: [min, max]` | `min`, `max` | Variable bounds |
|
||||||
|
| `goal` | `direction` | Objective direction |
|
||||||
|
|
||||||
|
**Example equivalent configs:**
|
||||||
|
```json
|
||||||
|
// Old format (UAV study style)
|
||||||
|
{"design_variables": [{"parameter": "angle", "bounds": [30, 60]}]}
|
||||||
|
|
||||||
|
// New format (beam study style)
|
||||||
|
{"design_variables": [{"name": "angle", "min": 30, "max": 60}]}
|
||||||
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Cross-References
|
## Cross-References
|
||||||
@@ -418,5 +437,6 @@ optimization_engine/
|
|||||||
|
|
||||||
| Version | Date | Changes |
|
| Version | Date | Changes |
|
||||||
|---------|------|---------|
|
|---------|------|---------|
|
||||||
|
| 2.1 | 2025-12-07 | Added config format flexibility (parameter/name, bounds/min-max, goal/direction) |
|
||||||
| 2.0 | 2025-12-07 | Added NNQualityAssessor with relative accuracy thresholds |
|
| 2.0 | 2025-12-07 | Added NNQualityAssessor with relative accuracy thresholds |
|
||||||
| 1.0 | 2025-12-06 | Initial implementation with 4 methods |
|
| 1.0 | 2025-12-06 | Initial implementation with 4 methods |
|
||||||
|
|||||||
@@ -486,12 +486,17 @@ class ProblemProfiler:
|
|||||||
# Extract design variables
|
# Extract design variables
|
||||||
design_vars = config.get('design_variables', [])
|
design_vars = config.get('design_variables', [])
|
||||||
profile.n_variables = len(design_vars)
|
profile.n_variables = len(design_vars)
|
||||||
profile.variable_names = [v['parameter'] for v in design_vars]
|
# Support both 'parameter' and 'name' keys for variable naming
|
||||||
|
profile.variable_names = [v.get('parameter') or v.get('name') for v in design_vars]
|
||||||
|
|
||||||
volume = 1.0
|
volume = 1.0
|
||||||
for var in design_vars:
|
for var in design_vars:
|
||||||
name = var['parameter']
|
name = var.get('parameter') or var.get('name')
|
||||||
bounds = var.get('bounds', [0, 1])
|
# Support both 'bounds' array and 'min'/'max' fields
|
||||||
|
if 'bounds' in var:
|
||||||
|
bounds = var['bounds']
|
||||||
|
else:
|
||||||
|
bounds = [var.get('min', 0), var.get('max', 1)]
|
||||||
profile.variable_bounds[name] = (bounds[0], bounds[1])
|
profile.variable_bounds[name] = (bounds[0], bounds[1])
|
||||||
profile.variable_types[name] = var.get('type', 'continuous')
|
profile.variable_types[name] = var.get('type', 'continuous')
|
||||||
volume *= (bounds[1] - bounds[0])
|
volume *= (bounds[1] - bounds[0])
|
||||||
@@ -501,7 +506,11 @@ class ProblemProfiler:
|
|||||||
objectives = config.get('objectives', [])
|
objectives = config.get('objectives', [])
|
||||||
profile.n_objectives = len(objectives)
|
profile.n_objectives = len(objectives)
|
||||||
profile.objective_names = [o['name'] for o in objectives]
|
profile.objective_names = [o['name'] for o in objectives]
|
||||||
profile.objective_goals = {o['name']: o.get('goal', 'minimize') for o in objectives}
|
# Support both 'goal' and 'direction' keys for objective direction
|
||||||
|
profile.objective_goals = {
|
||||||
|
o['name']: o.get('goal') or o.get('direction', 'minimize')
|
||||||
|
for o in objectives
|
||||||
|
}
|
||||||
profile.is_multi_objective = profile.n_objectives > 1
|
profile.is_multi_objective = profile.n_objectives > 1
|
||||||
|
|
||||||
# Extract constraints
|
# Extract constraints
|
||||||
|
|||||||
Reference in New Issue
Block a user