From 93a5508c0773324ba451aebc22758af73851ed2b Mon Sep 17 00:00:00 2001 From: Antoine Date: Wed, 11 Feb 2026 16:29:45 +0000 Subject: [PATCH] Fix mass extraction + db close order + nan handling - Journal now extracts p173 mass expression and writes _temp_mass.txt - history.get_study_summary() called before history.close() - Optuna nan rejection: fallback to INFEASIBLE_MASS penalty - pyNastran warning 'nx 2512 not supported' is harmless (reads fine) --- optimization_engine/nx/solve_simulation.py | 25 +++++++++++++++++++ .../studies/01_doe_landscape/run_doe.py | 10 ++++++-- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/optimization_engine/nx/solve_simulation.py b/optimization_engine/nx/solve_simulation.py index a2fa3862..0ee4acc2 100644 --- a/optimization_engine/nx/solve_simulation.py +++ b/optimization_engine/nx/solve_simulation.py @@ -1170,6 +1170,31 @@ def solve_simple_workflow( f"[JOURNAL] Solve completed: {numsolved} solved, {numfailed} failed, {numskipped} skipped" ) + # Extract mass from geometry part expression (p173) and write to temp file + try: + mass_value = None + # Find geometry part (Beam.prt) + for part in theSession.Parts: + part_type = type(part).__name__ + if "fem" not in part_type.lower() and "sim" not in part_type.lower(): + # This is the geometry part — look for mass expression + for expr in part.Expressions: + if expr.Name == "p173": + mass_value = expr.Value + print(f"[JOURNAL] Mass expression p173 = {mass_value}") + break + break + + if mass_value is not None: + mass_file = os.path.join(working_dir, "_temp_mass.txt") + with open(mass_file, "w") as f: + f.write(f"p173={mass_value}\n") + print(f"[JOURNAL] Wrote mass to {mass_file}") + else: + print(f"[JOURNAL] WARNING: Could not find mass expression p173") + except Exception as e: + print(f"[JOURNAL] WARNING: Mass extraction failed: {e}") + # Save all try: anyPartsModified, partSaveStatus = theSession.Parts.SaveAll() diff --git a/projects/hydrotech-beam/studies/01_doe_landscape/run_doe.py b/projects/hydrotech-beam/studies/01_doe_landscape/run_doe.py index 283d718d..0fc53203 100644 --- a/projects/hydrotech-beam/studies/01_doe_landscape/run_doe.py +++ b/projects/hydrotech-beam/studies/01_doe_landscape/run_doe.py @@ -255,6 +255,12 @@ def evaluate_trial( ) history.export_csv() # Live update CSV after each trial + # Optuna rejects nan — use INFEASIBLE_MASS as fallback + import math + if math.isnan(nx_result.mass): + logger.warning("Trial %d: mass is NaN (extraction failed), using penalty value", trial_num) + return INFEASIBLE_MASS + return nx_result.mass @@ -542,10 +548,10 @@ def run_study(args: argparse.Namespace) -> None: # Cleanup solver.close() - # Final history export + summary - history.close() + # Final history summary (before close!) hist_summary = history.get_study_summary(study_name) logger.info("History DB: %d total records across all studies", hist_summary["total"]) + history.close() def _progress_callback(study: optuna.Study, trial: optuna.trial.FrozenTrial) -> None: