Skip to content

Commit

Permalink
merge from main
Browse files Browse the repository at this point in the history
  • Loading branch information
jgsdavies committed Oct 7, 2024
2 parents 6c999c3 + 378875f commit 550c5d6
Show file tree
Hide file tree
Showing 8 changed files with 124 additions and 32 deletions.
File renamed without changes.
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "flit_core.buildapi"

[project]
name="ansys-motorcad-core"
version = "0.6.dev0"
version = "0.7.dev0"
description = "Pythonic interface to Ansys Motor-CAD."
readme = "README.rst"
requires-python = ">=3.8"
Expand Down Expand Up @@ -43,7 +43,7 @@ tests = [
doc = [
"Sphinx==8.0.2",
"numpydoc==1.8.0",
"ansys-sphinx-theme==1.0.9",
"ansys-sphinx-theme==1.1.2",
"sphinx-copybutton==0.5.2",
"sphinx-gallery==0.17.1",
"matplotlib",
Expand Down
13 changes: 7 additions & 6 deletions src/ansys/motorcad/core/geometry.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,10 @@ def __init__(self, motorcad_instance=None):
self._child_names = []
self._motorcad_instance = motorcad_instance
self._region_type = RegionType.adaptive
self.mesh_length = 0
self._linked_region = None
self._singular = False

# expect other properties to be implemented here including number duplications, material etc

def __eq__(self, other):
"""Override the default equals implementation for Region."""
return (
Expand Down Expand Up @@ -189,6 +188,9 @@ def _from_json(cls, json, motorcad_instance=None):
new_region.parent_name = json["parent_name"]
new_region._child_names = json["child_names"]

if "mesh_length" in json:
new_region.mesh_length = json["mesh_length"]

if "singular" in json:
new_region._singular = json["singular"]

Expand All @@ -214,6 +216,7 @@ def _to_json(self):
"entities": _convert_entities_to_json(self.entities),
"parent_name": self.parent_name,
"region_type": self._region_type.value,
"mesh_length": self.mesh_length,
"on_boundary": False if self._linked_region is None else True,
"singular": self._singular,
}
Expand Down Expand Up @@ -259,8 +262,7 @@ def parent_name(self, name):

@property
def linked_region(self):
"""Get linked duplication/unite region
"""
"""Get linked duplication/unite region."""
return self._linked_region

@linked_region.setter
Expand All @@ -270,8 +272,7 @@ def linked_region(self, region):

@property
def singular(self):
"""Get linked duplication/unite region
"""
"""Get linked duplication/unite region."""
return self._singular

@singular.setter
Expand Down
59 changes: 43 additions & 16 deletions src/ansys/motorcad/core/geometry_drawing.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

"""Unit containing region drawing functions."""
from copy import deepcopy
import warnings
from warnings import warn

from ansys.motorcad.core.geometry import Arc, Coordinate, Entity, Line, Region
Expand All @@ -35,6 +36,8 @@
except ImportError:
MATPLOTLIB_AVAILABLE = False

_MAX_RECURSION = 100


class _RegionDrawing:
def __init__(self, ax, stored_coords):
Expand All @@ -46,11 +49,25 @@ def _get_plot_range(self):
x_min, x_max = self.ax.get_xlim()
return x_max - x_min

def _find_coord_no_overlap(self, entity_coord):
def _find_coord_no_overlap(self, entity_coord, tried_coords, modifier):
# adjust depending on text size
# 0.04 good compromise
overlap_tol = 0.04
result = deepcopy(entity_coord)

recursion_depth = len(tried_coords)

if recursion_depth > _MAX_RECURSION:
return None

if entity_coord in tried_coords:
# Already tried this coordinate
# Might be flip-flopping between 2 points
# Add a small amount to how far we move the coord to try and force out of pattern
modifier += 0.01

tried_coords += [entity_coord]

for stored_coord in self.stored_coords:
difference = (entity_coord - stored_coord) / self._get_plot_range()

Expand All @@ -62,25 +79,35 @@ def _find_coord_no_overlap(self, entity_coord):
unit_vector = difference / abs(difference)

if abs(difference) < overlap_tol:
result += unit_vector * overlap_tol * self._get_plot_range() * 1.1
result = self._find_coord_no_overlap(result)
result += unit_vector * overlap_tol * self._get_plot_range() * (1.1 + modifier)
result = self._find_coord_no_overlap(result, tried_coords, modifier)
break
return result

def _plot_text_no_overlap(self, point, text, colour):
new_coord = self._find_coord_no_overlap(point)
self.stored_coords += [new_coord]
self.ax.annotate(
text,
xy=(point.x, point.y),
xytext=(
new_coord.x + 0.04 * self._get_plot_range(),
new_coord.y + 0.04 * self._get_plot_range(),
),
ha="right",
arrowprops=dict(arrowstyle="->", shrinkA=0, color=colour, alpha=0.5),
color=colour,
)
# Reset params for recursive function
tried_coords = []
modifier = 0

new_coord = self._find_coord_no_overlap(point, tried_coords, modifier)

if new_coord is None:
warning_str = "Failed to plot all labels on graph"
warnings.warn(warning_str)
self.ax.set_title("Warning : " + warning_str, color="red")
else:
self.stored_coords += [new_coord]
self.ax.annotate(
text,
xy=(point.x, point.y),
xytext=(
new_coord.x + 0.04 * self._get_plot_range(),
new_coord.y + 0.04 * self._get_plot_range(),
),
ha="right",
arrowprops=dict(arrowstyle="->", shrinkA=0, color=colour, alpha=0.5),
color=colour,
)

def draw_region(self, region, colour):
"""Draw a region."""
Expand Down
15 changes: 14 additions & 1 deletion src/ansys/motorcad/core/methods/adaptive_geometry.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@
# SOFTWARE.

"""Methods for adaptive geometry."""
from ansys.motorcad.core.geometry import Region
from warnings import warn

from ansys.motorcad.core.geometry import Region, RegionMagnet
from ansys.motorcad.core.rpc_client_core import is_running_in_internal_scripting


Expand Down Expand Up @@ -118,6 +120,17 @@ def set_region(self, region):
Motor-CAD region object.
"""
self.connection.ensure_version_at_least("2024.0")

if isinstance(region, RegionMagnet):
if (region._br_multiplier != 0.0) or (region._magnet_angle != 0.0):
# User has changed magnet properties that do not exist in older Motor-CAD API
if not self.connection.check_version_at_least("2024.2"):
warn("Setting magnet properties is only available in Motor-CAD 2024R2 or later")

if region.mesh_length != 0:
if not self.connection.check_version_at_least("2025"):
warn("Setting region mesh length is only available in Motor-CAD 2025R1 or later")

raw_region = region._to_json()

method = "SetRegion"
Expand Down
22 changes: 21 additions & 1 deletion tests/test_geometry.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
_orientation_of_three_points,
rt_to_xy,
)
import ansys.motorcad.core.rpc_client_core as rpc_client_core
from ansys.motorcad.core.rpc_client_core import DEFAULT_INSTANCE, set_default_instance


Expand Down Expand Up @@ -351,6 +352,7 @@ def test_region_from_json():
"parent_name": "Insulation",
"child_names": ["Duct", "Duct_1"],
"region type": "Adaptive Region",
"mesh_length": 0.035,
"singular": False,
}

Expand All @@ -365,7 +367,8 @@ def test_region_from_json():
test_region.entities = []
test_region.parent_name = "Insulation"
test_region._child_names = ["Duct", "Duct_1"]
test_region.singular = False,
test_region.mesh_length = (0.035,)
test_region.singular = (False,)

region = geometry.Region._from_json(raw_region)

Expand All @@ -384,6 +387,7 @@ def test_region_to_json():
"entities": [],
"parent_name": "Insulation",
"region_type": "Adaptive Region",
"mesh_length": 0.035,
"singular": True,
"on_boundary": False,
}
Expand All @@ -398,6 +402,7 @@ def test_region_to_json():
test_region.duplications = 10
test_region.entities = []
test_region.parent_name = "Insulation"
test_region.mesh_length = 0.035
test_region.singular = True
test_region.linked_region = None

Expand Down Expand Up @@ -1912,3 +1917,18 @@ def test_get_set_region_magnet(mc):
assert magnet.br_value == 1.31
assert magnet.br_used == 1.31 * 2
assert magnet.region_type == RegionType.magnet


def test_get_set_region_compatibility(mc, monkeypatch):
monkeypatch.setattr(mc.connection, "program_version", "2024.1")
monkeypatch.setattr(rpc_client_core, "DONT_CHECK_MOTORCAD_VERSION", False)
test_region = RegionMagnet()
test_region.br_multiplier = 2
with pytest.warns(UserWarning):
mc.set_region(test_region)

test_region = Region()
test_region.mesh_length = 0.1

with pytest.warns(UserWarning):
mc.set_region(test_region)
41 changes: 36 additions & 5 deletions tests/test_geometry_drawing.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,13 @@
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
from matplotlib import pyplot as plt
import pytest

from ansys.motorcad.core.geometry import Coordinate, Line, Region
import ansys.motorcad.core.geometry_drawing
from ansys.motorcad.core.geometry_drawing import draw_objects

# from matplotlib import pyplot as plt
# import pytest
#
# from ansys.motorcad.core.geometry import Arc, Coordinate, Line
# from ansys.motorcad.core.geometry_drawing import draw_objects, draw_objects_debug
# from ansys.motorcad.core.rpc_client_core import DEFAULT_INSTANCE, set_default_instance

drawing_flag = False
Expand All @@ -35,6 +36,36 @@ def set_drawing_flag(*args, **kwargs):
drawing_flag = True


def create_triangle_reg(bottom_left_coord):
region = Region()
region.name = "region " + str(bottom_left_coord)
c1 = bottom_left_coord
c2 = bottom_left_coord + Coordinate(10, 0)
c3 = bottom_left_coord + Coordinate(5, 5)
region.add_entity(Line(c1, c2))
region.add_entity(Line(c2, c3))
region.add_entity(Line(c3, c1))
return region


def test_label_recursion(monkeypatch):
# Stop plt.show() blocking tests
global drawing_flag
drawing_flag = False
monkeypatch.setattr(plt, "show", set_drawing_flag)

# add your geometry template here using PyMotorCAD
r1 = create_triangle_reg(Coordinate(0, 0))
r2 = create_triangle_reg(Coordinate(0, 0.2))
r3 = create_triangle_reg(Coordinate(0, 0.1))

draw_objects([r1, r2, r3])

monkeypatch.setattr(ansys.motorcad.core.geometry_drawing, "_MAX_RECURSION", 1)
with pytest.warns():
draw_objects([r1, r2, r3])


# def test_draw_objects_debug(mc, monkeypatch):
# # Just check it runs for now
# # Stop plt.show() blocking tests
Expand Down
2 changes: 1 addition & 1 deletion tests/test_graphs.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def test_get_magnetic_graph_point(mc):

x, y = mc.get_magnetic_graph_point("TorqueVW", 3)
assert almost_equal(x, 360)
assert almost_equal(y, 181, 0)
assert almost_equal(y, 182, 0)


def test_get_temperature_graph_point(mc):
Expand Down

0 comments on commit 550c5d6

Please sign in to comment.