Files
Atomizer/tests/journal_open_run_sim.py
Anto01 2729bd3278 feat: Add journal-based NX solver integration for optimization
Implements NX solver integration that connects to running Simcenter3D GUI
to solve simulations using the journal API. This approach handles licensing
properly and ensures fresh output files are generated for each iteration.

**New Components:**
- optimization_engine/nx_solver.py: Main solver wrapper with auto-detection
- optimization_engine/solve_simulation.py: NX journal script for batch solving
- examples/test_journal_optimization.py: Complete optimization workflow test
- examples/test_nx_solver.py: Solver integration tests
- tests/journal_*.py: Reference journal files for NX automation

**Key Features:**
- Auto-detects NX installation and version
- Connects to running NX GUI session (uses existing license)
- Closes/reopens .sim files to force reload of updated .prt files
- Deletes old output files to force fresh solves
- Waits for background solve completion
- Saves simulation to ensure all outputs are written
- ~4 second solve time per iteration

**Workflow:**
1. Update parameters in .prt file (nx_updater.py)
2. Close any open parts in NX session
3. Open .sim file fresh from disk (loads updated .prt)
4. Reload components and switch to FEM component
5. Solve in background mode
6. Save .sim file
7. Wait for .op2/.f06 to appear
8. Extract results from fresh .op2

**Tested:**
- Multiple iteration loop (3+ iterations)
- Files regenerated fresh each time (verified by timestamps)
- Complete parameter update -> solve -> extract workflow

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-15 12:23:57 -05:00

75 lines
3.3 KiB
Python

# NX 2412
# Journal created by antoi on Sat Nov 15 11:49:43 2025 Eastern Standard Time
#
import math
import NXOpen
import NXOpen.Assemblies
import NXOpen.CAE
import NXOpen.MenuBar
import NXOpen.UserDefinedObjects
def main(args) :
theSession = NXOpen.Session.GetSession() #type: NXOpen.Session
# ----------------------------------------------
# Menu: File->Open...
# ----------------------------------------------
basePart1, partLoadStatus1 = theSession.Parts.OpenActiveDisplay("C:\\Users\\antoi\\Documents\\Atomaste\\Atomizer\\tests\\Bracket_sim1.sim", NXOpen.DisplayPartOption.AllowAdditional)
workSimPart = theSession.Parts.BaseWork
displaySimPart = theSession.Parts.BaseDisplay
partLoadStatus1.Dispose()
theSession.ApplicationSwitchImmediate("UG_APP_SFEM")
# User Function call - UF_translate_variable
# User Function call - UF_TEXT_ask_text_mode
baseTemplateManager1 = theSession.XYPlotManager.TemplateManager
simPart1 = workSimPart
theSession.Post.UpdateUserGroupsFromSimPart(simPart1)
markId1 = theSession.SetUndoMark(NXOpen.Session.MarkVisibility.Visible, "Make Work Part")
component1 = workSimPart.ComponentAssembly.RootComponent.FindObject("COMPONENT Bracket_fem1 1")
partLoadStatus2 = theSession.Parts.SetWorkComponent(component1, NXOpen.PartCollection.RefsetOption.Entire, NXOpen.PartCollection.WorkComponentOption.Visible)
workFemPart = theSession.Parts.BaseWork
partLoadStatus2.Dispose()
markId2 = theSession.SetUndoMark(NXOpen.Session.MarkVisibility.Visible, "Make Work Part")
partLoadStatus3 = theSession.Parts.SetWorkComponent(NXOpen.Assemblies.Component.Null, NXOpen.PartCollection.RefsetOption.Entire, NXOpen.PartCollection.WorkComponentOption.Visible)
workSimPart = theSession.Parts.BaseWork # Bracket_sim1
partLoadStatus3.Dispose()
# ----------------------------------------------
# Menu: Analysis->Solve...
# ----------------------------------------------
markId3 = theSession.SetUndoMark(NXOpen.Session.MarkVisibility.Visible, "Start")
theSession.SetUndoMarkName(markId3, "Solve Dialog")
markId4 = theSession.SetUndoMark(NXOpen.Session.MarkVisibility.Invisible, "Solve")
theSession.DeleteUndoMark(markId4, None)
markId5 = theSession.SetUndoMark(NXOpen.Session.MarkVisibility.Invisible, "Solve")
theCAESimSolveManager = NXOpen.CAE.SimSolveManager.GetSimSolveManager(theSession)
psolutions1 = [NXOpen.CAE.SimSolution.Null] * 1
simSimulation1 = workSimPart.FindObject("Simulation")
simSolution1 = simSimulation1.FindObject("Solution[Solution 1]")
psolutions1[0] = simSolution1
numsolutionssolved1, numsolutionsfailed1, numsolutionsskipped1 = theCAESimSolveManager.SolveChainOfSolutions(psolutions1, NXOpen.CAE.SimSolution.SolveOption.Solve, NXOpen.CAE.SimSolution.SetupCheckOption.CompleteDeepCheckAndOutputErrors, NXOpen.CAE.SimSolution.SolveMode.Background)
theSession.DeleteUndoMark(markId5, None)
theSession.SetUndoMarkName(markId3, "Solve")
# ----------------------------------------------
# Menu: Tools->Automation->Journal->Stop Recording
# ----------------------------------------------
if __name__ == '__main__':
main(sys.argv[1:])