Workflow

The integrated motor workflow

The integrated motor workflow is cufemlab's flagship pipeline: a single .run() call that returns a multi-physics verdict — flux density, peak winding temperature, rotor safety factor — with full provenance.

Pipeline

materials.yaml ──┐
                 ├── magnetics_integrated   ──► B (T)
geometry  ───────┤
                 ├── thermal_integrated     ──► T_max (K)
inputs    ───────┤
                 ├── mechanics_integrated   ──► safety_factor
                 │
                 └── reporting             ──► signed PDF + JSON + hash

Inputs

ArgumentTypeNotes
materialspath to YAMLRequired. One of the 53 cited entries, or your own (NDA path).
stator_odfloat, mStator outer diameter.
current_afloat, APhase current (RMS).
slot_temp_kfloat, KAmbient slot temperature for thermal model.
coolingstr"natural" or "forced" (forced uses conjugate-heat path).
safety_factor_targetfloatFor the PASS/FAIL test on rotor stress (default 5.0).

Outputs

The returned Result object carries:

FieldMeaning
verdictOverall PASS / PARTIAL / MODEL_MISMATCH / FAIL.
BPeak airgap flux density, T.
T_maxPeak winding temperature, K.
safety_factorRotor mechanical safety factor against yield.
provenanceSHA-256 of inputs + materials + code.
checksPer-suite verdict trail (ref / tol / err).
cuda_event_ms> 0 if a GPU kernel ran (GPU evidence).

Example

⚠ Illustrative — this snippet is NOT runnable as‑is. The block below shows the conceptual server‑side engine API (what the platform computes internally). The cufemlab engine runs on the GPU server and is never installed locally, so import cufemlab raises ModuleNotFoundError in a notebook. To actually run an analysis from your Jupyter session, use the installed cufemlab_client SDK shown in “Runnable example” below.

Conceptual (engine‑side, illustrative only):

import cufemlab as cf   # illustrative only - the engine runs server-side, not a local import

motor = cf.workflows.IntegratedMotorWorkflow(
    materials = "materials/m19_steel.yaml",
)

result = motor.run(
    stator_od            = 0.20,
    current_a            = 12.0,
    slot_temp_k          = 393,
    cooling              = "natural",
    safety_factor_target = 5.0,
)

print("verdict        :", result.verdict)
print("B (T)          :", result.B)
print("T_max (°C)     :", result.T_max - 273.15)
print("safety factor  :", result.safety_factor)
print("provenance     :", result.provenance)

for check in result.checks:
    print(f"  {check.suite:24} {check.verdict:10} err {check.error*100:.2f}%  tol {check.tolerance*100:.1f}%  ref {check.reference}")

Runnable example (cufemlab_client SDK)

This is the real package installed in your Jupyter session. It submits the analysis to the SaaS API and polls for the result. Create an API key first under API keys in the app, then paste this into a notebook cell.

# Proprietary and confidential. Copyright Secrotec / Eba Turan. All rights reserved.
from cufemlab_client import Client          # the package actually installed in the notebook

client  = Client(api_key="cfm_...")         # create your key under "API keys" in the app
project = client.create_project("PMSM test")

# Submit a motor analysis (uploads your geometry, queues the job server-side).
job = client.analyze_motor(
    project.id,
    "motor.stl",
    analysis_type = "demo_motor_quick_check",   # free-tier-eligible smoke test
    gpu           = False,
)
job.wait(poll_interval=10)
result = job.result()

print("verdict :", result.verdict)
print("value   :", result.value)
print("notes   :", result.notes)
result.download_report("report.pdf")        # signed PDF + provenance

Reading the verdict

An overall PASS means every sub-suite passed against its cited reference within the declared tolerance. A PARTIAL means one or more sub-suites returned a verdict outside tolerance — the pipeline does not hide this, and the offending sub-suite is in result.checks. A MODEL_MISMATCH means the inputs landed in a regime the model does not yet cover (e.g. a fluid Re > 0 request in v0.3.0).

Determinism & provenance

The same inputs + the same materials + the same code always produce the same provenance hash. The hash is computed over the canonicalised YAML inputs, the materials file, and a content hash of the loaded cufemlab modules. Reports that fail to match a recomputed hash are flagged with ProvenanceError rather than allowed to ship.

Reporting

report = cf.reporting.Report(result, output_dir="reports/motor_v1/")
report.write_pdf()       # signed PDF (full verdict trail + provenance)
report.write_json()      # machine-readable
report.write_markdown()  # for PRs and reviews

Next steps