fix: mass extraction NaN in Hydrotech Beam DOE — two bugs
Bug 1 — Journal (solve_simulation.py simple workflow): Expression lookup for p173 fails silently for derived/measurement expressions, so _temp_mass.txt was never written. Added MeasureManager fallback via extract_part_mass() (already used in assembly workflow). Bug 2 — Extractor (extract_mass_from_expression.py): Journal writes 'p173=<value>' format but extractor tried float() on the whole content including 'p173='. Added key=value parsing. Defense in depth — nx_interface.py: Added stdout parsing fallback: if _temp_mass.txt still missing, parse mass from journal output captured via solver.py stdout passthrough. Files changed: - optimization_engine/nx/solve_simulation.py — MeasureManager fallback - optimization_engine/extractors/extract_mass_from_expression.py — key=value parse - optimization_engine/nx/solver.py — include stdout in result dict - projects/hydrotech-beam/studies/01_doe_landscape/nx_interface.py — stdout fallback Tags: hydrotech-beam, mass-extraction
This commit is contained in:
@@ -1170,28 +1170,49 @@ 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
|
||||
# Extract mass and write to _temp_mass.txt
|
||||
# Strategy: try expression lookup first, fall back to MeasureManager
|
||||
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
|
||||
|
||||
# Attempt 1: Read mass from expression p173 on geometry part
|
||||
try:
|
||||
for part in theSession.Parts:
|
||||
part_type = type(part).__name__
|
||||
if "fem" not in part_type.lower() and "sim" not in part_type.lower():
|
||||
for expr in part.Expressions:
|
||||
if expr.Name == "p173":
|
||||
mass_value = expr.Value
|
||||
print(f"[JOURNAL] Mass expression p173 = {mass_value}")
|
||||
break
|
||||
break
|
||||
except Exception as expr_err:
|
||||
print(f"[JOURNAL] Expression lookup failed: {expr_err}")
|
||||
|
||||
# Attempt 2: Use MeasureManager (more reliable for derived/measurement expressions)
|
||||
if mass_value is None:
|
||||
print(f"[JOURNAL] Expression p173 not found, using MeasureManager fallback...")
|
||||
geom_part = None
|
||||
for part in theSession.Parts:
|
||||
part_type = type(part).__name__
|
||||
if "fem" not in part_type.lower() and "sim" not in part_type.lower():
|
||||
geom_part = part
|
||||
break
|
||||
if geom_part is not None:
|
||||
try:
|
||||
mass_value = extract_part_mass(theSession, geom_part, working_dir)
|
||||
print(f"[JOURNAL] MeasureManager mass = {mass_value}")
|
||||
except Exception as mm_err:
|
||||
print(f"[JOURNAL] MeasureManager failed: {mm_err}")
|
||||
|
||||
# Write mass file (extract_part_mass may have already written it, but ensure consistency)
|
||||
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")
|
||||
print(f"[JOURNAL] WARNING: Could not extract mass via expression or MeasureManager")
|
||||
except Exception as e:
|
||||
print(f"[JOURNAL] WARNING: Mass extraction failed: {e}")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user