diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 21f5349..d809b9b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -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//` | 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 `_f_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 @@ -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//`, 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. diff --git a/motors/motor1.py b/motors/synrm_3f_36s.py similarity index 99% rename from motors/motor1.py rename to motors/synrm_3f_36s.py index ce1c118..5b10713 100644 --- a/motors/motor1.py +++ b/motors/synrm_3f_36s.py @@ -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 diff --git a/motors/motor2.py b/motors/synrm_5f_40s.py similarity index 98% rename from motors/motor2.py rename to motors/synrm_5f_40s.py index 7e1527a..d33e294 100644 --- a/motors/motor2.py +++ b/motors/synrm_5f_40s.py @@ -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" @@ -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] diff --git a/notebooks/run.py b/notebooks/run.py index ecba004..cc58a40 100644 --- a/notebooks/run.py +++ b/notebooks/run.py @@ -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"] diff --git a/notebooks/run_optimization.py b/notebooks/run_optimization.py index 2df015e..c61d40b 100644 --- a/notebooks/run_optimization.py +++ b/notebooks/run_optimization.py @@ -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) diff --git a/tests/test_ansys_regression.py b/tests/test_ansys_regression.py index 9fdbb0d..158f597 100644 --- a/tests/test_ansys_regression.py +++ b/tests/test_ansys_regression.py @@ -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 diff --git a/tests/test_design.py b/tests/test_synrm_3f_36s.py similarity index 98% rename from tests/test_design.py rename to tests/test_synrm_3f_36s.py index bdeae90..2c35e5c 100644 --- a/tests/test_design.py +++ b/tests/test_synrm_3f_36s.py @@ -2,7 +2,7 @@ import pytest -from motors.motor1 import Computation, Geometry +from motors.synrm_3f_36s import Computation, Geometry @pytest.fixture diff --git a/tests/test_design2.py b/tests/test_synrm_5f_40s.py similarity index 92% rename from tests/test_design2.py rename to tests/test_synrm_5f_40s.py index 4384e38..dc7f97a 100644 --- a/tests/test_design2.py +++ b/tests/test_synrm_5f_40s.py @@ -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):