Skip to content
Open
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
16 changes: 8 additions & 8 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"configurations": [
{
"name": "Python: Current File (Integrated Terminal)",
"type": "python",
"type": "debugpy",
"request": "launch",
"program": "${file}",
"console": "integratedTerminal",
Expand All @@ -17,14 +17,14 @@
},
{
"name": "Python: Code gen (GUI Ui only)",
"type": "python",
"type": "debugpy",
"request": "launch",
"program": "${workspaceFolder}/pyleecan/Generator/run_generate_GUI.py",
"console": "integratedTerminal"
},
{
"name": "Python: Code gen (GUI resources only)",
"type": "python",
"type": "debugpy",
"request": "launch",
"program": "${workspaceFolder}/pyleecan/Generator/run_generate_GUI_resources.py",
"console": "integratedTerminal",
Expand All @@ -34,7 +34,7 @@
},
{
"name": "Python: Code gen (Classes from csv)",
"type": "python",
"type": "debugpy",
"request": "launch",
"program": "${workspaceFolder}/pyleecan/Generator/run_generate_classes.py",
"console": "integratedTerminal",
Expand All @@ -45,7 +45,7 @@
},
{
"name": "Python: Run GUI",
"type": "python",
"type": "debugpy",
"request": "launch",
"program": "${workspaceFolder}/pyleecan/run_GUI.py",
"console": "integratedTerminal",
Expand All @@ -56,7 +56,7 @@
},
{
"name": "Python: Run class gen GUI",
"type": "python",
"type": "debugpy",
"request": "launch",
"program": "${workspaceFolder}/pyleecan/Generator/run_class_generator_GUI.py",
"console": "integratedTerminal",
Expand All @@ -67,7 +67,7 @@
},
{
"name": "Python: Run script",
"type": "python",
"type": "debugpy",
"request": "launch",
"program": "${workspaceFolder}/script.py",
"console": "integratedTerminal",
Expand All @@ -78,7 +78,7 @@
},
{
"name": "Python: Current File (External Terminal)",
"type": "python",
"type": "debugpy",
"request": "launch",
"program": "${file}",
"console": "externalTerminal"
Expand Down
145 changes: 145 additions & 0 deletions Tests/Methods/Machine/test_bore_and_notch.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
from os.path import join

import matplotlib.pyplot as plt
import pytest
from numpy import pi
from pyleecan.Classes.NotchEvenDist import NotchEvenDist
from pyleecan.Classes.BoreSinePole import BoreSinePole
from pyleecan.Classes.BoreFlower import BoreFlower
from pyleecan.Classes.SlotCirc import SlotCirc
from pyleecan.Classes.SlotW26 import SlotW26
from pyleecan.definitions import DATA_DIR
from pyleecan.Functions.load import load

mm = 1e-3


@pytest.mark.IPMSM
@pytest.mark.SCIM
def test_bore_and_notch_merge_type_0(is_show_fig=False):
"""Validation of bore shape and notches"""

# Load machines
Toyota_Prius = load(join(DATA_DIR, "Machine", "Toyota_Prius.json"))

# Add notches to Toyota_Prius
p = Toyota_Prius.get_pole_pair_number()

Nq = SlotCirc(Zs=2 * p, W0=5 * mm, H0=2 * mm)
NCirc1 = SlotCirc(Zs=2 * p, W0=8 * mm, H0=2 * mm)

a0 = 0.2

Toyota_Prius.rotor.notch = [
NotchEvenDist(alpha=0, notch_shape=Nq), # q-axis notch -> test sym. cut
NotchEvenDist(alpha=0.5 * pi / p + a0, notch_shape=NCirc1), # wide notch
NotchEvenDist(alpha=0.5 * pi / p - a0, notch_shape=NCirc1), # wide notch
]
delta_d = Toyota_Prius.stator.Rint - Toyota_Prius.rotor.Rext
Toyota_Prius.rotor.bore = BoreSinePole(
N=8, delta_d=delta_d, delta_q=3 * mm, W0=50 * mm
)
Toyota_Prius.rotor.bore.type_merge_slot = 0

Toyota_Prius.plot(sym=8, is_show_fig=is_show_fig)
Toyota_Prius.plot(is_show_fig=is_show_fig)

return Toyota_Prius


@pytest.mark.IPMSM
@pytest.mark.SCIM
def test_bore_and_notch_merge_type_1(is_show_fig=False):
"""Validation of rotor and stator notches"""

# Load machines
Toyota_Prius = load(join(DATA_DIR, "Machine", "Toyota_Prius.json"))
Audi_eTron = load(join(DATA_DIR, "Machine", "AUDI_eTron.json"))

# Add notches to Toyota_Prius
p = Toyota_Prius.get_pole_pair_number()

Nq = SlotW26(Zs=2 * p, W0=1 * mm, H0=4 * mm, H1=0, R1=3 * mm, R2=3 * mm)
NCirc1 = SlotCirc(Zs=2 * p, W0=8 * mm, H0=2 * mm)
NCirc2 = SlotCirc(Zs=2 * p, W0=3 * mm, H0=1 * mm)
NSlotW26 = SlotW26(Zs=2 * p, W0=1 * mm, H0=2 * mm, H1=0, R1=3 * mm, R2=3 * mm)

a0 = 0.2
a1 = 0.33

Toyota_Prius.rotor.notch = [
NotchEvenDist(alpha=0, notch_shape=Nq), # q-axis notch -> test sym. cut
NotchEvenDist(alpha=0.5 * pi / p + a0, notch_shape=NCirc1), # wide notch
NotchEvenDist(alpha=0.5 * pi / p - a0, notch_shape=NCirc1), # wide notch
NotchEvenDist(
alpha=0.5 * pi / p + a1, notch_shape=NCirc2
), # cut out completely
NotchEvenDist(alpha=0.5 * pi / p, notch_shape=NSlotW26), # small notch
]
delta_d = Toyota_Prius.stator.Rint - Toyota_Prius.rotor.Rext
Toyota_Prius.rotor.bore = BoreSinePole(
N=8, delta_d=delta_d, delta_q=5 * mm, W0=50 * mm
)

Toyota_Prius.plot(sym=8, is_show_fig=is_show_fig)
Toyota_Prius.plot(is_show_fig=is_show_fig)

# Add notches to Audi_eTron
NBs = SlotCirc(Zs=16, W0=0.001, H0=0.0005)
NBr = SlotCirc(Zs=29, W0=0.001, H0=0.0005)

Audi_eTron.stator.notch = [NotchEvenDist(alpha=0, notch_shape=NBs)]
Audi_eTron.rotor.notch = [NotchEvenDist(alpha=0, notch_shape=NBr)]
Audi_eTron.stator.slot.H0 = 4 * mm
Audi_eTron.stator.bore = BoreFlower(N=4, Rarc=Audi_eTron.stator.Rint + 10 * mm)

Audi_eTron.plot(sym=2, is_show_fig=is_show_fig)
Audi_eTron.plot(is_show_fig=is_show_fig)

return Toyota_Prius, Audi_eTron


@pytest.mark.IPMSM
@pytest.mark.SCIM
def test_bore_and_notch_merge_type_2(is_show_fig=False):
"""Validation of rotor and stator notches"""

# Load machines
Toyota_Prius = load(join(DATA_DIR, "Machine", "Toyota_Prius.json"))

# Add notches to Toyota_Prius
p = Toyota_Prius.get_pole_pair_number()

Nq = SlotW26(Zs=2 * p, W0=1 * mm, H0=4 * mm, H1=0, R1=3 * mm, R2=3 * mm)
NCirc1 = SlotCirc(Zs=2 * p, W0=8 * mm, H0=2 * mm)
NCirc2 = SlotCirc(Zs=2 * p, W0=3 * mm, H0=1 * mm)
NSlotW26 = SlotW26(Zs=2 * p, W0=1 * mm, H0=2 * mm, H1=0, R1=3 * mm, R2=3 * mm)

a0 = 0.2
a1 = 0.33

Toyota_Prius.rotor.notch = [
NotchEvenDist(alpha=0, notch_shape=Nq), # q-axis notch -> test sym. cut
NotchEvenDist(alpha=0.5 * pi / p + a0, notch_shape=NCirc1), # wide notch
NotchEvenDist(alpha=0.5 * pi / p - a0, notch_shape=NCirc1), # wide notch
NotchEvenDist(alpha=0.5 * pi / p + a1, notch_shape=NCirc2), # cut out at all
NotchEvenDist(alpha=0.5 * pi / p, notch_shape=NSlotW26), # small notch
]
delta_d = Toyota_Prius.stator.Rint - Toyota_Prius.rotor.Rext
Toyota_Prius.rotor.bore = BoreSinePole(
N=8, delta_d=delta_d, delta_q=5 * mm, W0=50 * mm
)

Toyota_Prius.rotor.bore.type_merge_slot = 2

Toyota_Prius.plot(sym=8, is_show_fig=is_show_fig)
Toyota_Prius.plot(is_show_fig=is_show_fig)

return Toyota_Prius


if __name__ == "__main__":
# Toyota_Prius = test_bore_and_notch_merge_type_0(is_show_fig=True)
# Toyota_Prius, Audi_eTron = test_bore_and_notch_merge_type_1(is_show_fig=True)
Toyota_Prius = test_bore_and_notch_merge_type_2(is_show_fig=True)
print("Done")
86 changes: 83 additions & 3 deletions pyleecan/Functions/Geometry/cut_lines_between_angle.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,100 @@ def cut_lines_between_angles(line_list, begin_angle, end_angle):
cut_lines : [Line]
Cut lines between the two angles
"""
# normalize angles according to numpy.angle range, i.e. (-pi, pi]
begin_angle = angle(exp(1j * begin_angle))
end_angle = angle(exp(1j * end_angle))

# rotate list in case first/last line is in between begin and end angle
# first copy list
rotated_list = [line for line in line_list]
# rotate until first line is before begin angle
rotate = True
ii = 0
while rotate:
ang = angle(rotated_list[0].get_begin())
if (begin_angle <= end_angle) and (ang < begin_angle or ang > end_angle):
rotate = False
elif (
end_angle < ang < begin_angle
): # begin and end angle cross -pi, pi boundary
rotate = False
if rotate:
rotated_list.append(rotated_list.pop(0))
ii += 1
if ii >= len(rotated_list): # rotation failed
rotate = False

first_cut = list()
cut_lines = list()
# First cut
for line in line_list:
for line in rotated_list:
top_split_list, _ = line.split_line(0, exp(1j * begin_angle))
first_cut.extend(top_split_list)
# Second cut
for line in first_cut:
_, bot_split_list = line.split_line(0, exp(1j * end_angle))
cut_lines.extend(bot_split_list)

# plot_cut_line(line_list, begin_angle, end_angle, first_cut, cut_lines)

# Check that lines are in the correct way
if (angle(cut_lines[0].get_begin()) % (2 * pi)) - (begin_angle % (2 * pi)) > 1e-6:
cut_lines = cut_lines[::-1]
if len(cut_lines) > 1:
EPS = 1e-6
c1 = abs(angle(cut_lines[0].get_begin() * exp(-1j * end_angle)))
c2 = abs(angle(cut_lines[0].get_end() * exp(-1j * end_angle)))
c3 = abs(angle(cut_lines[-1].get_begin() * exp(-1j * begin_angle)))
c4 = abs(angle(cut_lines[-1].get_end() * exp(-1j * begin_angle)))
if (c1 < EPS or c2 < EPS) and (c3 < EPS or c4 < EPS):
cut_lines = cut_lines[::-1]

return cut_lines


def plot_cut_line(line_list, begin_angle, end_angle, first_cut, cut_lines):
"""Plot the original lines and the cut lines
Parameters
----------
line_list : [Line]
list of line to cut
begin_angle : float
Begin angle of the cut [rad]
end_angle : float
End angle of the cut [rad]

"""
import matplotlib.pyplot as plt

fig = plt.figure()
ax = fig.add_subplot(111)

r = 0
for line in line_list:
z1 = line.get_begin()
z2 = line.get_end()
ax.plot([z1.real, z2.real], [z1.imag, z2.imag], color="gray")
r = max(r, abs(z1), abs(z2))

# plot cut lines
z1 = r * exp(1j * begin_angle)
z2 = r * exp(1j * end_angle)

ax.plot([z1.real, -z1.real], [z1.imag, -z1.imag], color="r")
ax.plot([z2.real, -z2.real], [z2.imag, -z2.imag], color="b")

for line in first_cut:
z1 = line.get_begin()
z2 = line.get_end()
ax.plot([z1.real, z2.real], [z1.imag, z2.imag], color="k")
r = max(r, abs(z1), abs(z2))

for line in cut_lines:
z1 = line.get_begin()
z2 = line.get_end()
ax.plot([z1.real, z2.real], [z1.imag, z2.imag], color="k", marker=".")
r = max(r, abs(z1), abs(z2))

# axis to equal size
ax.axis("equal")

plt.show()
5 changes: 3 additions & 2 deletions pyleecan/Methods/Geometry/Segment/is_on_line.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@


def is_on_line(self, Z):
"""Check is a point defined by its complex coordinate is on the segment
"""Check if a point defined by its complex coordinate is on the segment

Parameters
----------
Expand All @@ -26,6 +26,7 @@ def is_on_line(self, Z):
if abs(Z12.real * Z13.imag - Z12.imag * Z13.real) < 1e-10:
K13 = Z12.real * Z13.real + Z12.imag * Z13.imag
K12 = Z12.real * Z12.real + Z12.imag * Z12.imag
if K13 >= 0 and K13 <= K12:
eps = 1e-12
if K13 >= -eps and K13 <= K12 + eps:
return True
return False
37 changes: 13 additions & 24 deletions pyleecan/Methods/Machine/Bore/merge_slot_connect.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
def merge_slot_connect(self, radius_desc_list, prop_dict, sym):
"""Merge the Bore shape with notches/slot on the bore/yoke
Connect method: Add lines between radius and notch/slot
(To use when the radius shape have circular part matchine the radius
(To use when the radius shape have circular part matching the radius
or when radius lines are bellow normal radius)

Parameters
Expand Down Expand Up @@ -61,6 +61,7 @@ def merge_slot_connect(self, radius_desc_list, prop_dict, sym):
radius_desc_list[-1]["lines"] = lines

# Apply merge strategy on slot/notch
siz = len(radius_desc_list)
line_list = list()
for ii, desc_dict in enumerate(radius_desc_list):
if desc_dict["label"] == "Radius":
Expand All @@ -72,30 +73,18 @@ def merge_slot_connect(self, radius_desc_list, prop_dict, sym):
line.prop_dict.update(prop_dict)
line_list.extend(desc_dict["lines"])
else: # Connect and add notch lines
lines = desc_dict["lines"]
if len(line_list) > 0:
# Connect Radius to slot/notch by Segment (if needed)
if (
abs(line_list[-1].get_end() - desc_dict["lines"][0].get_begin())
> 1e-6
):
line_list.append(
Segment(
line_list[-1].get_end(), desc_dict["lines"][0].get_begin()
)
)
line_list.extend(desc_dict["lines"])
if abs(line_list[-1].get_end() - lines[0].get_begin()) > 1e-6:
connection = Segment(line_list[-1].get_end(), lines[0].get_begin())
line_list.append(connection)
line_list.extend(lines)

# Connect slot/notch to next radius
if (
abs(
radius_desc_list[ii + 1]["lines"][0].get_begin()
- desc_dict["lines"][-1].get_end()
)
> 1e-6
):
line_list.append(
Segment(
desc_dict["lines"][-1].get_end(),
radius_desc_list[ii + 1]["lines"][0].get_begin(),
)
)
next_lines = radius_desc_list[(ii + 1) % siz]["lines"]
if abs(next_lines[0].get_begin() - lines[-1].get_end()) > 1e-6:
connection = Segment(lines[-1].get_end(), next_lines[0].get_begin())
if not (sym != 1 and ii == (siz - 1)):
line_list.append(connection)
return line_list
Loading