femagtools 1.8.17__py3-none-any.whl → 1.8.19__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- femagtools/__init__.py +1 -1
- femagtools/airgap.py +5 -1
- femagtools/bch.py +23 -6
- femagtools/dxfsl/area.py +35 -23
- femagtools/dxfsl/areabuilder.py +97 -58
- femagtools/dxfsl/converter.py +11 -1
- femagtools/dxfsl/fslrenderer.py +3 -0
- femagtools/dxfsl/geom.py +265 -63
- femagtools/dxfsl/machine.py +128 -9
- femagtools/dxfsl/symmetry.py +20 -5
- femagtools/femag.py +27 -16
- femagtools/isa7.py +25 -22
- femagtools/machine/__init__.py +3 -1
- femagtools/machine/effloss.py +18 -4
- femagtools/machine/pm.py +88 -74
- femagtools/machine/sm.py +32 -21
- femagtools/mcv.py +4 -1
- femagtools/plot/bch.py +3 -1
- femagtools/plot/char.py +5 -16
- femagtools/plot/nc.py +67 -34
- femagtools/shortcircuit.py +18 -10
- femagtools/templates/psi-torq-rem.mako +4 -4
- femagtools/templates/statorKS1.mako +43 -0
- femagtools/utils.py +5 -4
- {femagtools-1.8.17.dist-info → femagtools-1.8.19.dist-info}/METADATA +2 -2
- {femagtools-1.8.17.dist-info → femagtools-1.8.19.dist-info}/RECORD +31 -30
- tests/test_machine.py +1 -2
- {femagtools-1.8.17.dist-info → femagtools-1.8.19.dist-info}/WHEEL +0 -0
- {femagtools-1.8.17.dist-info → femagtools-1.8.19.dist-info}/entry_points.txt +0 -0
- {femagtools-1.8.17.dist-info → femagtools-1.8.19.dist-info}/licenses/LICENSE +0 -0
- {femagtools-1.8.17.dist-info → femagtools-1.8.19.dist-info}/top_level.txt +0 -0
femagtools/dxfsl/geom.py
CHANGED
@@ -35,7 +35,7 @@ from .functions import middle_angle, positive_angle
|
|
35
35
|
from .functions import normalise_angle, is_same_angle
|
36
36
|
from .functions import part_of_circle, gcd
|
37
37
|
from .functions import point_on_arc, points_on_line, nodes_are_equal
|
38
|
-
from .functions import area_size
|
38
|
+
from .functions import area_size, get_angle_of_arc
|
39
39
|
import io
|
40
40
|
import time
|
41
41
|
|
@@ -401,11 +401,11 @@ class Geometry(object):
|
|
401
401
|
for n in self.g.nodes()}
|
402
402
|
nx.relabel_nodes(self.g, mapping, copy=False)
|
403
403
|
|
404
|
-
def
|
404
|
+
def get_rotated_nodes(self, alpha, nodes):
|
405
405
|
T = np.array(((np.cos(alpha), -np.sin(alpha)),
|
406
406
|
(np.sin(alpha), np.cos(alpha))))
|
407
|
-
|
408
|
-
return
|
407
|
+
nodes = [T.dot(np.array((n[0], n[1]))).tolist() for n in nodes]
|
408
|
+
return nodes
|
409
409
|
|
410
410
|
def rotate(self, alpha):
|
411
411
|
"""rotates all objects by angle alpha"""
|
@@ -1142,20 +1142,30 @@ class Geometry(object):
|
|
1142
1142
|
rtol=self.rtol,
|
1143
1143
|
atol=self.atol)
|
1144
1144
|
|
1145
|
-
def get_corner_nodes(self, center, angle):
|
1146
|
-
rtol = 1e-4
|
1147
|
-
atol = 1e-4
|
1148
|
-
|
1145
|
+
def get_corner_nodes(self, center, angle, rtol=1e-4, atol=1e-4):
|
1149
1146
|
center_added, corners = self.get_corner_list(center, angle, rtol, atol)
|
1150
1147
|
if len(corners) < 2:
|
1151
1148
|
return () # not enough corners
|
1152
1149
|
return (corners[0].point(), corners[len(corners)-1].point())
|
1153
1150
|
|
1154
|
-
def set_start_corners(self, center, angle):
|
1155
|
-
self.start_corners = self.get_corner_nodes(center, angle)
|
1151
|
+
def set_start_corners(self, center, angle, rtol=1e-4, atol=1e-4):
|
1152
|
+
self.start_corners = self.get_corner_nodes(center, angle, rtol=rtol, atol=atol)
|
1153
|
+
|
1154
|
+
def set_end_corners(self, center, angle, rtol=1e-4, atol=1e-4):
|
1155
|
+
self.end_corners = self.get_corner_nodes(center, angle, rtol=rtol, atol=atol)
|
1156
|
+
|
1157
|
+
def set_virtual_start_end_corners(self):
|
1158
|
+
assert(not self.start_corners)
|
1159
|
+
assert(not self.end_corners)
|
1156
1160
|
|
1157
|
-
|
1158
|
-
|
1161
|
+
dist_list = [(distance(self.center, n), n) for n in self.nodes()]
|
1162
|
+
dist_list.sort()
|
1163
|
+
d1, c1 = dist_list[0]
|
1164
|
+
d2, c2 = dist_list[-1]
|
1165
|
+
corners = (c1, c2)
|
1166
|
+
self.start_corners = corners
|
1167
|
+
self.end_corners = corners
|
1168
|
+
return
|
1159
1169
|
|
1160
1170
|
def get_angle(self, alpha1, alpha2):
|
1161
1171
|
if np.isclose(alpha1, alpha2, 0.001, 0.001):
|
@@ -1172,7 +1182,7 @@ class Geometry(object):
|
|
1172
1182
|
nx.set_edge_attributes(self.g, False, 1)
|
1173
1183
|
nx.set_edge_attributes(self.g, False, 2)
|
1174
1184
|
|
1175
|
-
def create_list_of_areas(self, main=False, delete=False):
|
1185
|
+
def create_list_of_areas(self, main=False, delete=False, nolog=True):
|
1176
1186
|
""" return list of areas for each node and their neighbors
|
1177
1187
|
"""
|
1178
1188
|
if delete: # clear list of areas
|
@@ -1183,7 +1193,7 @@ class Geometry(object):
|
|
1183
1193
|
# list already available
|
1184
1194
|
return
|
1185
1195
|
|
1186
|
-
areabuilder = AreaBuilder(geom=self)
|
1196
|
+
areabuilder = AreaBuilder(geom=self, nolog=nolog)
|
1187
1197
|
areabuilder.create_list_of_areas(main=main)
|
1188
1198
|
self.area_list = areabuilder.area_list
|
1189
1199
|
logger.debug("area list created")
|
@@ -1904,6 +1914,19 @@ class Geometry(object):
|
|
1904
1914
|
self.area_list = []
|
1905
1915
|
return nodes_deleted > 0
|
1906
1916
|
|
1917
|
+
def delete_needless_elements(self, radius):
|
1918
|
+
self.area_list = []
|
1919
|
+
for e in self.elements():
|
1920
|
+
if greater(distance(self.center, e.p1), radius):
|
1921
|
+
self.remove_edge(e)
|
1922
|
+
elif greater(distance(self.center, e.p2), radius):
|
1923
|
+
self.remove_edge(e)
|
1924
|
+
elif is_Arc(e):
|
1925
|
+
p = e.center_of_connection()
|
1926
|
+
if greater(distance(self.center, p), radius):
|
1927
|
+
self.remove_edge(e)
|
1928
|
+
self.delete_all_appendices()
|
1929
|
+
|
1907
1930
|
def render_areagroups(self, renderer):
|
1908
1931
|
if not self.areagroup_list:
|
1909
1932
|
return
|
@@ -2036,11 +2059,47 @@ class Geometry(object):
|
|
2036
2059
|
return c
|
2037
2060
|
return None
|
2038
2061
|
|
2062
|
+
def check_hull_radius(self, center, radius, hull_points):
|
2063
|
+
logger.debug("check_hull_radius")
|
2064
|
+
min_r = radius
|
2065
|
+
max_r = radius
|
2066
|
+
for p in hull_points:
|
2067
|
+
d = round(distance(center, p), 2)
|
2068
|
+
min_r = min(min_r, d)
|
2069
|
+
max_r = max(max_r, d)
|
2070
|
+
|
2071
|
+
if min_r > radius * 0.8:
|
2072
|
+
# radius is ok, adjust hill line
|
2073
|
+
return True, max_r > radius
|
2074
|
+
|
2075
|
+
return False, False
|
2076
|
+
|
2039
2077
|
def get_machine_part(self, mm):
|
2040
2078
|
logger.debug("*** Begin of get_machine_part() ***")
|
2041
2079
|
|
2042
2080
|
h_points = [h for h in convex_hull(self.virtual_nodes())]
|
2043
|
-
center = self.
|
2081
|
+
center, radius = self.get_center_arcs(mm)
|
2082
|
+
if center and radius:
|
2083
|
+
center_left = round(center[0] - mm[0], 4)
|
2084
|
+
center_right = round(mm[1] - center[0], 4)
|
2085
|
+
center_down = round(center[1] - mm[2], 4)
|
2086
|
+
center_up = round(mm[3] - center[1], 4)
|
2087
|
+
min_r = min(center_left, center_right, center_up, center_down)
|
2088
|
+
max_r = max(center_left, center_right, center_up, center_down)
|
2089
|
+
is_full = min_r > max_r / 2
|
2090
|
+
|
2091
|
+
ok, adjust_hull = self.check_hull_radius(center, radius, h_points)
|
2092
|
+
if is_full and ok:
|
2093
|
+
self.set_center([round(center[0], 8), round(center[1], 8)])
|
2094
|
+
self.area_list = []
|
2095
|
+
machine = Machine(self,
|
2096
|
+
radius=radius,
|
2097
|
+
startangle=0.0,
|
2098
|
+
endangle=0.0)
|
2099
|
+
return machine
|
2100
|
+
|
2101
|
+
center = self.get_center(center, h_points, mm)
|
2102
|
+
|
2044
2103
|
logger.debug(" - Center is %s", center)
|
2045
2104
|
|
2046
2105
|
min_radius = 99999
|
@@ -2259,9 +2318,14 @@ class Geometry(object):
|
|
2259
2318
|
def is_same_center(self, center_lst, center, rtol, atol):
|
2260
2319
|
for c in center_lst:
|
2261
2320
|
if points_are_close(c['center'], center['center'], rtol, atol):
|
2262
|
-
|
2263
|
-
|
2264
|
-
|
2321
|
+
new_radius, new_phi = center['radiuslist'][0]
|
2322
|
+
c_radiuslist = [r for r, p in c['radiuslist']]
|
2323
|
+
try:
|
2324
|
+
i = c_radiuslist.index(new_radius)
|
2325
|
+
c_radius, c_phi = c['radiuslist'][i]
|
2326
|
+
c['radiuslist'][i][1] = c_phi + new_phi
|
2327
|
+
except:
|
2328
|
+
c['radiuslist'].append([new_radius, new_phi])
|
2265
2329
|
c['count'] = c['count'] + 1
|
2266
2330
|
return True
|
2267
2331
|
return False
|
@@ -2283,7 +2347,6 @@ class Geometry(object):
|
|
2283
2347
|
return None
|
2284
2348
|
cy_list = [(c['center'][0], c) for c in c_list]
|
2285
2349
|
cy_list.sort()
|
2286
|
-
[logger.info("y=%s, c=%s", y, c) for y, c in cy_list]
|
2287
2350
|
y, c = cy_list[0]
|
2288
2351
|
return c
|
2289
2352
|
|
@@ -2302,14 +2365,23 @@ class Geometry(object):
|
|
2302
2365
|
return True
|
2303
2366
|
return False
|
2304
2367
|
|
2368
|
+
def get_best_radius(radiuslist):
|
2369
|
+
radiuslist.sort(reverse=True)
|
2370
|
+
r1, phi1 = radiuslist[0]
|
2371
|
+
for r2, phi2 in radiuslist[1:]:
|
2372
|
+
if phi2 > phi1:
|
2373
|
+
return r2
|
2374
|
+
break
|
2375
|
+
return r1
|
2376
|
+
|
2305
2377
|
circles = [e for e in self.elements() if is_Circle(e)]
|
2306
2378
|
logger.debug(" -- %s Circles", len(circles))
|
2307
2379
|
|
2308
2380
|
for e in circles:
|
2309
2381
|
center = (round(e.center[0], 3), round(e.center[1], 3))
|
2382
|
+
angle = e.get_angle_of_arc()
|
2310
2383
|
entry = {'center': center,
|
2311
|
-
'
|
2312
|
-
'phi': e.get_angle_of_arc(),
|
2384
|
+
'radiuslist': [[round(e.radius, 1), angle]],
|
2313
2385
|
'dist': e.length(),
|
2314
2386
|
'inside': center_is_inside(center),
|
2315
2387
|
'count': 1}
|
@@ -2320,9 +2392,9 @@ class Geometry(object):
|
|
2320
2392
|
|
2321
2393
|
for e in arcs:
|
2322
2394
|
center = (round(e.center[0], 3), round(e.center[1], 3))
|
2395
|
+
angle = e.get_angle_of_arc()
|
2323
2396
|
entry = {'center': center,
|
2324
|
-
'
|
2325
|
-
'phi': e.get_angle_of_arc(),
|
2397
|
+
'radiuslist': [[round(e.radius, 1), angle]],
|
2326
2398
|
'dist': e.length(),
|
2327
2399
|
'inside': center_is_inside(center),
|
2328
2400
|
'count': 1}
|
@@ -2330,7 +2402,7 @@ class Geometry(object):
|
|
2330
2402
|
center_list.append(entry)
|
2331
2403
|
|
2332
2404
|
center = None
|
2333
|
-
arc_list = [[c['count'], len(c['
|
2405
|
+
arc_list = [[c['count'], len(c['radiuslist']), n, c]
|
2334
2406
|
for n, c in enumerate(center_list)]
|
2335
2407
|
arc_list.sort(reverse=True)
|
2336
2408
|
|
@@ -2340,63 +2412,63 @@ class Geometry(object):
|
|
2340
2412
|
[logger.debug("Arc %s", arc) for arc in arc_list]
|
2341
2413
|
if not arc_list:
|
2342
2414
|
logger.debug("end of get_center_arcs: no arcs")
|
2343
|
-
return None
|
2415
|
+
return None, 0
|
2344
2416
|
|
2345
|
-
cnt, cr1,
|
2417
|
+
cnt, cr1, n, c1 = arc_list[0]
|
2346
2418
|
logger.debug("First Entry: %s", c1)
|
2347
2419
|
center = c1['center']
|
2420
|
+
radius = get_best_radius(c1['radiuslist'])
|
2348
2421
|
if len(arc_list) > 1:
|
2349
|
-
cnt, cr2,
|
2422
|
+
cnt, cr2, n, c2 = arc_list[1]
|
2350
2423
|
logger.debug("Second Entry: %s", c2)
|
2351
2424
|
if not cr1 > cr2:
|
2352
2425
|
center = None
|
2353
2426
|
|
2354
2427
|
if center:
|
2355
|
-
logger.debug("end of get_center_arcs:
|
2356
|
-
return center
|
2428
|
+
logger.debug("end of get_center_arcs: c=%s, r=%s", center, radius)
|
2429
|
+
return center, radius
|
2357
2430
|
|
2358
2431
|
c_entry = self.get_center_with_x(center_list, x_min)
|
2359
2432
|
if c_entry:
|
2360
2433
|
center = c_entry['center']
|
2361
2434
|
if center[1] < y_min:
|
2362
|
-
logger.debug("end of get_center_arcs
|
2363
|
-
return center
|
2435
|
+
logger.debug("end of get_center_arcs (x): c=%s", center)
|
2436
|
+
return center, 0
|
2437
|
+
|
2364
2438
|
c_entry = self.get_center_with_y(center_list, y_min)
|
2365
2439
|
if c_entry:
|
2366
2440
|
center = c_entry['center']
|
2367
2441
|
if center[0] < x_min:
|
2368
|
-
logger.debug("end of get_center_arcs
|
2369
|
-
return center
|
2442
|
+
logger.debug("end of get_center_arcs (y): c=%s", center)
|
2443
|
+
return center, 0
|
2370
2444
|
|
2371
2445
|
logger.debug("end of get_center_arcs: no center found")
|
2372
|
-
return None
|
2446
|
+
return None, 0
|
2373
2447
|
|
2374
2448
|
def get_center_dim(self, mm):
|
2375
2449
|
return (round(mm[0], 4), round(mm[2], 4))
|
2376
2450
|
|
2377
|
-
def get_center(self,
|
2378
|
-
logger.debug("Begin of get_center(%s points)", len(
|
2379
|
-
if len(
|
2451
|
+
def get_center(self, center_arcs, hull_points, mm):
|
2452
|
+
logger.debug("Begin of get_center(%s hull-points)", len(hull_points))
|
2453
|
+
if len(hull_points) < 3:
|
2380
2454
|
return None
|
2381
2455
|
|
2382
2456
|
center = None
|
2383
2457
|
# Zuerst suchen wir anhand der Circle- und Arc-Segmente nach einem
|
2384
2458
|
# möglichen Center-Punkt.
|
2385
|
-
center_arcs = self.get_center_arcs(mm)
|
2386
|
-
|
2387
2459
|
if center_arcs:
|
2388
2460
|
center = center_arcs
|
2389
2461
|
else:
|
2390
2462
|
# Wir finden keine Arc-Objekte, welche uns einen Hinweis auf den
|
2391
2463
|
# Center geben können. Wir versuchen in der Verzweiflung mit
|
2392
2464
|
# center_hull oder x(min) und y(min)
|
2393
|
-
center_hull = self.get_center_hull(
|
2465
|
+
center_hull = self.get_center_hull(_hull_points)
|
2394
2466
|
if center_hull:
|
2395
2467
|
center = center_hull
|
2396
2468
|
else:
|
2397
2469
|
center = self.get_center_dim(mm)
|
2398
2470
|
|
2399
|
-
center_xaxis = self.get_center_xaxis(
|
2471
|
+
center_xaxis = self.get_center_xaxis(hull_points)
|
2400
2472
|
y = center_xaxis[1]
|
2401
2473
|
if y is not None:
|
2402
2474
|
if np.isclose(y, center[1], atol=0.3):
|
@@ -3265,6 +3337,31 @@ class Geometry(object):
|
|
3265
3337
|
return [a for a in self.list_of_areas()
|
3266
3338
|
if a.is_type(type)]
|
3267
3339
|
|
3340
|
+
def is_tooth(self, a, windings, wdg_min_dist, wdg_max_dist):
|
3341
|
+
if a.around_windings(windings, self):
|
3342
|
+
if a.close_to_ag:
|
3343
|
+
return True
|
3344
|
+
if self.is_inner:
|
3345
|
+
if greater(a.min_dist, wdg_min_dist, atol=1e-1):
|
3346
|
+
return True
|
3347
|
+
else:
|
3348
|
+
if less(a.max_dist, wdg_max_dist, atol=1e-1):
|
3349
|
+
return True
|
3350
|
+
return False
|
3351
|
+
|
3352
|
+
def between_airgap_and_winding(self, a,
|
3353
|
+
wdg_min_angle,
|
3354
|
+
wdg_max_angle,
|
3355
|
+
wdg_min_dist,
|
3356
|
+
wdg_max_dist):
|
3357
|
+
if greater_equal(a.min_angle, wdg_min_angle) and \
|
3358
|
+
less_equal(a.max_angle, wdg_max_angle):
|
3359
|
+
if self.is_inner:
|
3360
|
+
return less_equal(wdg_max_dist, a.min_dist)
|
3361
|
+
else:
|
3362
|
+
return less_equal(a.max_dist, wdg_min_dist)
|
3363
|
+
return False
|
3364
|
+
|
3268
3365
|
def collect_windings(self):
|
3269
3366
|
logger.debug("begin of collect_windings")
|
3270
3367
|
good_windings = self.get_windings(AREA.TYPE_WINDINGS)
|
@@ -3337,7 +3434,7 @@ class Geometry(object):
|
|
3337
3434
|
max_size, max_w = windings_surface[0]
|
3338
3435
|
for sz, w in windings_surface[1:]:
|
3339
3436
|
logger.debug("winding size = %s", sz)
|
3340
|
-
if sz / max_size < 0.
|
3437
|
+
if sz / max_size < 0.60:
|
3341
3438
|
w.set_type(AREA.TYPE_AIR)
|
3342
3439
|
if sz / max_size < 0.2:
|
3343
3440
|
windings_found -= 1
|
@@ -3387,7 +3484,7 @@ class Geometry(object):
|
|
3387
3484
|
air_areas = [a for a in self.list_of_areas()
|
3388
3485
|
if a.is_type(AREA.TYPE_AIR_OR_IRON)]
|
3389
3486
|
for a in air_areas:
|
3390
|
-
if a.around_windings(windings, self):
|
3487
|
+
if a.around_windings(windings, self) and less(a.min_dist, wdg_max_dist - 0.5):
|
3391
3488
|
logger.debug("Area %s", a.identifier())
|
3392
3489
|
logger.debug(" - air-angle min/max = %s/%s",
|
3393
3490
|
a.min_air_angle,
|
@@ -3409,7 +3506,6 @@ class Geometry(object):
|
|
3409
3506
|
a.close_to_ag):
|
3410
3507
|
a.set_type(AREA.TYPE_AIR) # air
|
3411
3508
|
continue
|
3412
|
-
|
3413
3509
|
a.set_type(AREA.TYPE_TOOTH) # iron shaft (Zahn)
|
3414
3510
|
continue
|
3415
3511
|
|
@@ -3438,14 +3534,28 @@ class Geometry(object):
|
|
3438
3534
|
a.set_type(AREA.TYPE_TOOTH) # iron shaft (Zahn)
|
3439
3535
|
else:
|
3440
3536
|
logger.debug("#5 not around windings")
|
3441
|
-
|
3537
|
+
if self.between_airgap_and_winding(a,
|
3538
|
+
wdg_min_angle, wdg_max_angle,
|
3539
|
+
wdg_min_dist, wdg_max_dist):
|
3540
|
+
a.set_type(AREA.TYPE_AIR) # air
|
3541
|
+
else:
|
3542
|
+
if self.is_inner:
|
3543
|
+
if greater(a.min_dist, wdg_min_dist, atol=1e-1):
|
3544
|
+
a.set_type(AREA.TYPE_TOOTH) # iron shaft (Zahn)
|
3545
|
+
else:
|
3546
|
+
a.set_type(AREA.TYPE_YOKE) # iron shaft (Joch)
|
3547
|
+
else:
|
3548
|
+
if less(a.max_dist, wdg_max_dist, atol=1e-1):
|
3549
|
+
a.set_type(AREA.TYPE_TOOTH) # iron shaft (Zahn)
|
3550
|
+
else:
|
3551
|
+
a.set_type(AREA.TYPE_YOKE) # iron shaft (Joch)
|
3442
3552
|
|
3443
3553
|
# yoke or shaft ?
|
3444
3554
|
iron_areas = [a for a in self.list_of_areas()
|
3445
3555
|
if a.is_type(AREA.TYPE_YOKE)]
|
3446
3556
|
for a in iron_areas:
|
3447
3557
|
if a.around_windings(windings, self):
|
3448
|
-
if less(a.min_dist, wdg_max_dist):
|
3558
|
+
if less(a.min_dist, wdg_max_dist - 0.5):
|
3449
3559
|
if less_equal(a.max_dist, wdg_max_dist):
|
3450
3560
|
a.set_type(AREA.TYPE_TOOTH) # iron shaft (Zahn)
|
3451
3561
|
else:
|
@@ -3765,16 +3875,44 @@ class Geometry(object):
|
|
3765
3875
|
a_midangle = a.get_mid_angle(self.center)
|
3766
3876
|
if np.isclose(midangle, a_midangle, atol=1e-2, rtol=1e-2):
|
3767
3877
|
s = a.area_size()
|
3768
|
-
mags.append([s, n, a])
|
3878
|
+
mags.append([s, n, a, a_midangle])
|
3769
3879
|
|
3770
3880
|
if not mags:
|
3771
|
-
|
3881
|
+
logger.debug("possible_magnet_in_the_middle: No Areas for Magnets")
|
3882
|
+
return None
|
3883
|
+
|
3772
3884
|
mags.sort(reverse=True)
|
3773
|
-
|
3774
|
-
a
|
3775
|
-
|
3776
|
-
|
3777
|
-
|
3885
|
+
to_angle = np.pi / 2
|
3886
|
+
for s, n, a, mid in mags:
|
3887
|
+
angle = to_angle - mid
|
3888
|
+
nodelist = a.list_of_nodes()
|
3889
|
+
nodes = self.get_rotated_nodes(angle, nodelist)
|
3890
|
+
p1 = self.center
|
3891
|
+
p2 = point(self.center, self.max_radius + 10, mid)
|
3892
|
+
line = Line(Element(start=p1, end=p2))
|
3893
|
+
nodelist = a.get_intersect_points(line)
|
3894
|
+
mid_nodes = self.get_rotated_nodes(angle, nodelist)
|
3895
|
+
if self.is_possible_magnet(nodes, mid_nodes):
|
3896
|
+
a.set_type(AREA.TYPE_MAGNET_AIRGAP)
|
3897
|
+
a.phi = mid
|
3898
|
+
a.mag_width = (a.max_dist - a.min_dist) * 0.9
|
3899
|
+
return a
|
3900
|
+
|
3901
|
+
logger.debug("possible_magnet_in_the_middle: No Magnets")
|
3902
|
+
return None
|
3903
|
+
|
3904
|
+
def is_possible_magnet(self, all_nodes, mid_nodes):
|
3905
|
+
all_y = [n[1] for n in all_nodes]
|
3906
|
+
all_y.sort()
|
3907
|
+
mid_y = [n[1] for n in mid_nodes]
|
3908
|
+
mid_y.sort()
|
3909
|
+
|
3910
|
+
logger.debug("is_possible_magnet: mid y min/max = %s/%s", mid_y[0], mid_y[-1])
|
3911
|
+
logger.debug("is_possible_magnet: all y min/max = %s/%s", all_y[0], all_y[-1])
|
3912
|
+
|
3913
|
+
if all_y[0] > mid_y[-1]:
|
3914
|
+
return False
|
3915
|
+
return True
|
3778
3916
|
|
3779
3917
|
def force_area_as_magnet(self, area):
|
3780
3918
|
for a in self.list_of_areas():
|
@@ -3804,20 +3942,33 @@ class Geometry(object):
|
|
3804
3942
|
return False
|
3805
3943
|
|
3806
3944
|
def looking_for_corners(self):
|
3807
|
-
|
3808
|
-
|
3809
|
-
|
3810
|
-
|
3811
|
-
|
3812
|
-
|
3813
|
-
|
3814
|
-
|
3815
|
-
|
3816
|
-
|
3945
|
+
try:
|
3946
|
+
if self.is_inner:
|
3947
|
+
logger.debug("looking_for_corners: inner")
|
3948
|
+
start_cp = self.start_corners[-1]
|
3949
|
+
end_cp = self.end_corners[-1]
|
3950
|
+
else:
|
3951
|
+
logger.debug("looking_for_corners: outer")
|
3952
|
+
start_cp = self.start_corners[0]
|
3953
|
+
end_cp = self.end_corners[0]
|
3954
|
+
logger.debug("looking_for_corners: start=%s, end=%s",
|
3955
|
+
start_cp, end_cp)
|
3956
|
+
except IndexError:
|
3957
|
+
return
|
3958
|
+
|
3817
3959
|
for area in self.list_of_areas():
|
3818
3960
|
area.mark_airgap_corners(start_cp, end_cp)
|
3819
3961
|
return
|
3820
3962
|
|
3963
|
+
def get_areas_of_type(self, types=()):
|
3964
|
+
return [area for area in self.list_of_areas()
|
3965
|
+
if area.type in types]
|
3966
|
+
|
3967
|
+
def get_areas_of_irons(self):
|
3968
|
+
return self.get_areas_of_type((AREA.TYPE_IRON,
|
3969
|
+
AREA.TYPE_YOKE,
|
3970
|
+
AREA.TYPE_TOOTH,))
|
3971
|
+
|
3821
3972
|
def num_areas_of_type(self, types=()):
|
3822
3973
|
return len([area for area in self.list_of_areas()
|
3823
3974
|
if area.type in types])
|
@@ -4164,6 +4315,16 @@ class Geometry(object):
|
|
4164
4315
|
for e in self.elements():
|
4165
4316
|
e.adjust_points()
|
4166
4317
|
|
4318
|
+
def split_with_point(self, p):
|
4319
|
+
for e in self.elements(Shape):
|
4320
|
+
elements = e.split([p])
|
4321
|
+
if elements:
|
4322
|
+
self.remove_edge(e)
|
4323
|
+
for e in elements:
|
4324
|
+
self.add_element(e, rtol=self.rtol, atol=self.atol)
|
4325
|
+
return True
|
4326
|
+
return False
|
4327
|
+
|
4167
4328
|
def split_and_get_intersect_points(self, el, aktion=True, include_end=True):
|
4168
4329
|
logger.debug("begin of split_and_get_intersect_points")
|
4169
4330
|
rtol = 1e-03
|
@@ -4320,6 +4481,41 @@ class Geometry(object):
|
|
4320
4481
|
builder = AreaBuilder(geom=self)
|
4321
4482
|
return builder.create_inner_corner_auxiliary_areas(startangle, endangle)
|
4322
4483
|
|
4484
|
+
def adjust_outer_hull_for_symmetry(self):
|
4485
|
+
logger.debug("adjust_outer_hull_for_symmetry()")
|
4486
|
+
areas = self.list_of_areas()
|
4487
|
+
builder = AreaBuilder(geom=self)
|
4488
|
+
op_nodes, op_el = builder.get_outer_opposite_airgap_line()
|
4489
|
+
if not op_nodes:
|
4490
|
+
logger.warning("Fatal: No nodes found")
|
4491
|
+
return False
|
4492
|
+
|
4493
|
+
radiuslist = {}
|
4494
|
+
n1 = op_nodes[0]
|
4495
|
+
d1 = distance(self.center, n1)
|
4496
|
+
a1 = alpha_line(self.center, n1)
|
4497
|
+
for n2 in op_nodes[1:]:
|
4498
|
+
d2 = distance(self.center, n2)
|
4499
|
+
a2 = alpha_line(self.center, n2)
|
4500
|
+
if np.isclose(d1, d2, rtol=1e-3, atol=1e-2):
|
4501
|
+
r = round((d1 + d2) / 2, 1)
|
4502
|
+
alpha = get_angle_of_arc(a2, a1)
|
4503
|
+
radius_alpha = radiuslist.get(r, 0.0) + alpha
|
4504
|
+
radiuslist[r] = radius_alpha
|
4505
|
+
|
4506
|
+
n1 = n2
|
4507
|
+
d1 = d2
|
4508
|
+
a1 = a2
|
4509
|
+
|
4510
|
+
rlist = [(radiuslist[r], r) for r in radiuslist]
|
4511
|
+
rlist.sort(reverse=True)
|
4512
|
+
alpha, best_radius = rlist[0]
|
4513
|
+
if np.isclose(best_radius, self.max_radius, rtol=1e-3, atol=1e-2):
|
4514
|
+
return False
|
4515
|
+
logger.debug("Best Outer Radius is %s", best_radius)
|
4516
|
+
self.adjust_outer_hull(best_radius)
|
4517
|
+
return True
|
4518
|
+
|
4323
4519
|
def close_outer_winding_areas(self):
|
4324
4520
|
logger.debug("begin close_outer_winding_areas(%s areas)",
|
4325
4521
|
len(self.area_list))
|
@@ -4641,3 +4837,9 @@ class Geometry(object):
|
|
4641
4837
|
|
4642
4838
|
with io.open(name, 'w', encoding='utf-8') as f:
|
4643
4839
|
f.write('\n'.join(content))
|
4840
|
+
|
4841
|
+
def adjust_outer_hull(self, new_radius):
|
4842
|
+
c = Circle(Element(center=self.center, radius=new_radius))
|
4843
|
+
self.add_element(c, 1e-3, 1e-3)
|
4844
|
+
self.delete_needless_elements(new_radius)
|
4845
|
+
self.max_radius = new_radius
|