Fix: FEM part lookup (exclude _i.prt), hole_count unit (Constant not mm), add file logging

- solve_simulation.py: FEM finder now excludes idealized parts, falls back to loading .fem
- solve_simulation.py: hole_count written as [Constant] not [MilliMeter] in .exp
- run_doe.py: dual logging to console + results/doe_run.log
This commit is contained in:
2026-02-11 14:17:43 +00:00
parent 126f0bb2e0
commit 0e459028fe
12 changed files with 49 additions and 7 deletions

View File

@@ -934,10 +934,21 @@ def solve_simple_workflow(
# Write expressions to temp file and import
exp_file_path = os.path.join(working_dir, "_temp_expressions.exp")
# Known integer/constant expressions (no unit)
CONSTANT_EXPRESSIONS = {
"hole_count",
}
with open(exp_file_path, "w") as f:
for expr_name, expr_value in expression_updates.items():
# Determine unit based on name
if "angle" in expr_name.lower():
# Determine unit based on expression type
if expr_name in CONSTANT_EXPRESSIONS:
unit_str = "Constant"
# Write as integer if it's a whole number
if expr_value == int(expr_value):
expr_value = int(expr_value)
elif "angle" in expr_name.lower():
unit_str = "Degrees"
else:
unit_str = "MilliMeter"
@@ -1009,14 +1020,32 @@ def solve_simple_workflow(
print(f"[JOURNAL] WARNING: Could not load idealized part: {e}")
break
# Find the FEM part
# Find the FEM part (must be .fem, NOT _i.prt idealized part)
fem_part = None
for part in theSession.Parts:
if "_fem" in part.Name.lower() or part.Name.lower().endswith(".fem"):
part_name = part.Name.lower()
# Match FEM parts but exclude idealized parts (_i)
if ("_fem" in part_name or part_name.endswith(".fem")) and "_i" not in part_name.split("_fem")[-1]:
fem_part = part
print(f"[JOURNAL] Found FEM part: {part.Name}")
break
# If not found by name, try loading .fem file from working directory
if fem_part is None:
for filename in os.listdir(working_dir):
if filename.lower().endswith(".fem"):
fem_path = os.path.join(working_dir, filename)
print(f"[JOURNAL] Loading FEM file: {filename}")
try:
loaded_part, partLoadStatus = theSession.Parts.Open(fem_path)
partLoadStatus.Dispose()
if loaded_part is not None:
fem_part = loaded_part
print(f"[JOURNAL] FEM part loaded: {fem_part.Name}")
break
except Exception as e:
print(f"[JOURNAL] WARNING: Could not load FEM: {e}")
if fem_part:
try:
# Switch to FEM part - CRITICAL: Use SameAsDisplay to make FEM the work part

View File

@@ -644,13 +644,26 @@ def main() -> None:
"""Entry point."""
args = parse_args()
# Configure logging
# Configure logging — console + file
log_level = logging.DEBUG if args.verbose else logging.INFO
log_format = "%(asctime)s [%(levelname)-7s] %(name)s: %(message)s"
log_datefmt = "%Y-%m-%d %H:%M:%S"
# Ensure results dir exists for log file
results_dir = Path(args.results_dir)
results_dir.mkdir(parents=True, exist_ok=True)
log_file = results_dir / "doe_run.log"
logging.basicConfig(
level=log_level,
format="%(asctime)s [%(levelname)-7s] %(name)s: %(message)s",
datefmt="%Y-%m-%d %H:%M:%S",
format=log_format,
datefmt=log_datefmt,
handlers=[
logging.StreamHandler(), # console
logging.FileHandler(log_file, mode="a", encoding="utf-8"), # file
],
)
logger.info("Log file: %s", log_file.resolve())
# Run
try: