Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 19 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,26 @@ If you find yourself editing `machine_design/`on your own branch, stop — that'
| `machine_design/optimization/` | design agnostic optimizers and geometry generators |
| `machine_design/parallel_calculation/` | parallel runners for sweeping many solves at once |
| `experiments/<name>/` | your run configs, the profile/objective you're studying, analysis notebooks, result artifacts, write-ups |
| `motors/` | concrete machine definitions (`motor1.py`, `motor2.py`), each subclassing the base `Geometry`/`Computation` classes |
| `motors/` | one module per **anchor** (a named machine), each subclassing the base `Geometry`/`Computation` classes |
| `tests/` | the test suite |

Add a new machine by subclassing an existing `motors/motor*.py` file instead of editing an existing class in place, so old results stay reproducible.
### Anchors — machines are named, not numbered

An **anchor** is a named machine definition: everything needed to instantiate and solve one physical machine — class, slots, phases, winding (turns, `Rs`), end-winding `Lew`, **rotor radii**, geometry generator + parameter bounds, FEA template.

The name carries only what the anchor fixes for good — machine class, phases, slot count. Values that are routinely swept (turns, currents, bus voltage) stay out of it, so a name never goes stale.

One anchor per module in `motors/`, named `<class>_<phases>f_<slots>s`:

| module | machine |
|---|---|
| `motors/synrm_3f_36s.py` | 3-phase SynRM, 36 stator slots |
| `motors/synrm_5f_40s.py` | 5-phase SynRM, 40 stator slots, dq1+dq3 excitation |

Each exports `Geometry` and `Computation`, so the module name carries the identity and the class names stay uniform — `from motors.synrm_5f_40s import Geometry, Computation` says which machine you are solving, where `Geometry2` did not.

- **Derive, don't fork.** To study a variant (add magnets, change turns), subclass an existing anchor and override only what differs — do **not** edit an anchor's class in place, so old results stay reproducible. A genuinely new machine is a new anchor module.
- **An anchor must declare all of the above**, rotor radii included. They are the radial window the barrier generators draw into; an anchor that does not set them cannot have a rotor built for it.

## Pull requests

Expand Down Expand Up @@ -60,7 +76,7 @@ All compute goes through the SLURM queue on `bayes` — see [`bayes-queue/README

**I want to optimize an existing machine with an existing method** → in `experiments/<name>/`, write a config that picks an anchor + a method + your objective/constraints, and an sbatch to run it. Touch nothing shared.

**I want to study a new machine** → add an **motors** (PR to `main`); if it's a variant, derive it from an existing anchor. Then use it from your experiment.
**I want to study a new machine** → add an **anchor** (PR to `main`); if it's a variant, derive it from an existing anchor. Then use it from your experiment.

**I want a new optimization method** → add it to `machine_design/optimization/` against the interface (PR to `main`). Now anyone can use it on any anchor.

Expand Down
2 changes: 2 additions & 0 deletions motors/motor1.py → motors/synrm_3f_36s.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
"""Anchor `synrm_3f_36s`: 3-phase synchronous reluctance machine, 36 stator slots."""

from ansys.aedt.core import Maxwell2d
from ansys.aedt.core.modeler.modeler_2d import Modeler2D

Expand Down
12 changes: 9 additions & 3 deletions motors/motor2.py → motors/synrm_5f_40s.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
"""Anchor `synrm_5f_40s`: 5-phase synchronous reluctance machine, 40 stator slots.

Derives from `synrm_3f_36s`, overriding only the slotting and winding it needs for five
phases. Excitation is dq1 + dq3.
"""

import numpy as np
from ansys.aedt.core import Maxwell2d

from machine_design.designs.computation import ComputationBase

from .motor1 import Geometry
from .synrm_3f_36s import Geometry as BaseGeometry


class Geometry2(Geometry):
class Geometry(BaseGeometry):
def set_geom_params(self):
super().set_geom_params()
self.geom_params["SlotNumber"] = "40"
Expand All @@ -22,7 +28,7 @@ def set_winds_params(self):
self.wind_params["Nc"] = "113"


class Computation2(ComputationBase):
class Computation(ComputationBase):
def set_oper_params(self):
f = 50 # [Hz]
RotSpeed = 60 * f / self.geometry.PolePairs # [rpm]
Expand Down
2 changes: 1 addition & 1 deletion notebooks/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
plot_barriers,
save_params,
)
from motors.motor1 import Computation, Geometry
from motors.synrm_3f_36s import Computation, Geometry

config = load_config()
aedt_version = config["aedt_version"]
Expand Down
2 changes: 1 addition & 1 deletion notebooks/run_optimization.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
objective,
objective_transform,
)
from motors.motor1 import Computation, Geometry
from motors.synrm_3f_36s import Computation, Geometry

torch.set_default_dtype(torch.float64)

Expand Down
2 changes: 1 addition & 1 deletion tests/test_ansys_regression.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
from machine_design.config import load_config
from machine_design.designs.design import Design as LiveDesign
from machine_design.optimization.generators import HacklGenerator_OneLambda
from motors.motor1 import Computation, Geometry
from motors.synrm_3f_36s import Computation, Geometry

pytestmark = pytest.mark.ansys

Expand Down
2 changes: 1 addition & 1 deletion tests/test_design.py → tests/test_synrm_3f_36s.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import pytest

from motors.motor1 import Computation, Geometry
from motors.synrm_3f_36s import Computation, Geometry


@pytest.fixture
Expand Down
10 changes: 5 additions & 5 deletions tests/test_design2.py → tests/test_synrm_5f_40s.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
import pytest

from motors.motor1 import Geometry
from motors.motor2 import Computation2, Geometry2
from motors.synrm_3f_36s import Geometry as BaseGeometry
from motors.synrm_5f_40s import Computation, Geometry


@pytest.fixture
def base_geometry():
return Geometry()
return BaseGeometry()


@pytest.fixture
def geometry2():
return Geometry2()
return Geometry()


@pytest.fixture
def computation2(geometry2):
return Computation2(geometry2)
return Computation(geometry2)


def test_geom_params_overrides_slot_number_only(base_geometry, geometry2):
Expand Down
Loading