feat: add adaptive isogrid tool — project foundations

- Python Brain: density field, constrained Delaunay triangulation,
  pocket profiles, profile assembly, validation modules
- NX Hands: skeleton scripts for geometry extraction, AFEM setup,
  per-iteration solve (require NX environment to develop)
- Atomizer integration: 15-param space definition, objective function
- Technical spec, README, sample test geometry, requirements.txt
- Architecture: Python Brain + NX Hands + Atomizer Manager
This commit is contained in:
2026-02-16 00:01:35 +00:00
parent cf82de4f06
commit 4bec4063a5
16 changed files with 2124 additions and 0 deletions

View File

@@ -0,0 +1,6 @@
"""
Adaptive Isogrid — NX Hands
NXOpen journal scripts for geometry extraction, AFEM setup, and per-iteration solve.
These scripts run inside NX Simcenter via the NXOpen Python API.
"""

View File

@@ -0,0 +1,28 @@
"""
NXOpen script — Build Interface Model (Model A) for Assembly FEM.
ONE-TIME: Creates spider elements (RBE2/RBE3) at each hole + edge BC nodes.
Exports interface_nodes.json for the iteration script.
NOTE: Skeleton — requires NX environment for development.
See docs/technical-spec.md Section 4.2 for full pseudocode.
"""
def build_interface_model(geometry_json_path, fem_part):
"""
Build Model A: spider elements at each hole + edge BC nodes.
For each hole:
- Center node (master)
- N circumference nodes (~1 per 2mm of circumference)
- RBE2 (rigid) or RBE3 (distributing) spider
For plate boundary:
- Edge nodes at ~3mm spacing
Exports interface_nodes.json with all node IDs and coordinates.
"""
raise NotImplementedError(
"Develop inside NX Simcenter. See docs/technical-spec.md Section 4.2."
)

View File

@@ -0,0 +1,54 @@
"""
NXOpen script — Extract plate geometry from selected face.
ONE-TIME: Run inside NX. User selects plate face, assigns hole weights.
Exports geometry.json for the Python brain.
NOTE: This is pseudocode / skeleton. Actual NXOpen API calls need
NX environment to develop and test.
"""
# This script runs inside NX — NXOpen is available at runtime
# import NXOpen
# import json
# import math
def extract_plate_geometry(face, hole_weights):
"""
Extract plate geometry from an NX face.
Parameters
----------
face : NXOpen.Face
The selected plate face.
hole_weights : dict
{loop_index: weight} from user input.
Returns
-------
dict : geometry definition for export.
"""
raise NotImplementedError(
"This script must be developed and tested inside NX Simcenter. "
"See docs/technical-spec.md Section 2 for full pseudocode."
)
def sample_edge(edge, tolerance=0.1):
"""Sample edge curve as polyline with given chord tolerance."""
# NXOpen: edge.GetCurve(), evaluate at intervals
raise NotImplementedError
def fit_circle(points):
"""Fit a circle to boundary points. Returns (center, diameter)."""
# Least-squares circle fit
raise NotImplementedError
def export_geometry(geometry, filepath='geometry.json'):
"""Export geometry dict to JSON."""
import json
with open(filepath, 'w') as f:
json.dump(geometry, f, indent=2)

View File

@@ -0,0 +1,35 @@
"""
NXOpen script — Per-iteration Model B rebuild + solve + extract.
LOOP: Called by Atomizer for each trial.
1. Delete old Model B geometry + mesh
2. Import new 2D ribbed profile from rib_profile.json
3. Mesh with hard-point seeds at interface node locations
4. Merge nodes in Assembly FEM
5. Solve (Nastran)
6. Extract results → results.json
NOTE: Skeleton — requires NX environment for development.
See docs/technical-spec.md Section 4.3 for full pseudocode.
"""
def iteration_solve(profile_path, interface_nodes_path, afem_part):
"""
Single optimization iteration.
Returns dict with status, mass, stress/displacement fields.
"""
raise NotImplementedError(
"Develop inside NX Simcenter. See docs/technical-spec.md Section 4.3."
)
def extract_results(afem, solution):
"""
Extract field results from solved assembly FEM.
Only from Model B elements (plate mesh), ignoring spiders.
"""
raise NotImplementedError(
"Develop inside NX Simcenter. See docs/technical-spec.md Section 4.3."
)