femagtools 1.8.2__py3-none-any.whl → 1.8.4__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- femagtools/__init__.py +1 -1
- femagtools/bch.py +10 -6
- femagtools/dxfsl/area.py +69 -1
- femagtools/dxfsl/conv.py +53 -16
- femagtools/dxfsl/converter.py +273 -76
- femagtools/dxfsl/fslrenderer.py +18 -22
- femagtools/dxfsl/functions.py +38 -8
- femagtools/dxfsl/geom.py +112 -35
- femagtools/dxfsl/journal.py +1 -1
- femagtools/dxfsl/machine.py +44 -7
- femagtools/dxfsl/shape.py +4 -0
- femagtools/dxfsl/symmetry.py +105 -32
- femagtools/femag.py +64 -61
- femagtools/fsl.py +4 -2
- femagtools/isa7.py +3 -2
- femagtools/machine/afpm.py +45 -25
- femagtools/machine/effloss.py +31 -20
- femagtools/machine/im.py +6 -8
- femagtools/machine/sizing.py +4 -3
- femagtools/machine/sm.py +35 -37
- femagtools/mcv.py +66 -37
- femagtools/multiproc.py +79 -80
- femagtools/parstudy.py +10 -4
- femagtools/semi_fea.py +108 -0
- femagtools/templates/basic_modpar.mako +0 -3
- femagtools/templates/fe-contr.mako +18 -18
- femagtools/templates/ld_lq_fast.mako +3 -0
- femagtools/templates/mesh-airgap.mako +6 -0
- femagtools/templates/mult_cal_fast.mako +3 -0
- femagtools/templates/pm_sym_f_cur.mako +4 -1
- femagtools/templates/pm_sym_fast.mako +3 -0
- femagtools/templates/pm_sym_loss.mako +3 -0
- femagtools/templates/psd_psq_fast.mako +3 -0
- femagtools/templates/torq_calc.mako +3 -0
- femagtools/tks.py +23 -20
- femagtools/utils.py +1 -1
- femagtools/windings.py +11 -4
- femagtools/zmq.py +213 -0
- {femagtools-1.8.2.dist-info → femagtools-1.8.4.dist-info}/METADATA +3 -3
- {femagtools-1.8.2.dist-info → femagtools-1.8.4.dist-info}/RECORD +49 -47
- {femagtools-1.8.2.dist-info → femagtools-1.8.4.dist-info}/WHEEL +1 -1
- tests/test_afpm.py +15 -6
- tests/test_femag.py +1 -1
- tests/test_fsl.py +4 -4
- tests/test_mcv.py +20 -14
- tests/test_parident.py +2 -1
- {femagtools-1.8.2.dist-info → femagtools-1.8.4.dist-info}/LICENSE +0 -0
- {femagtools-1.8.2.dist-info → femagtools-1.8.4.dist-info}/entry_points.txt +0 -0
- {femagtools-1.8.2.dist-info → femagtools-1.8.4.dist-info}/top_level.txt +0 -0
femagtools/dxfsl/geom.py
CHANGED
@@ -1986,7 +1986,7 @@ class Geometry(object):
|
|
1986
1986
|
startangle=0.0,
|
1987
1987
|
endangle=np.pi/2)
|
1988
1988
|
|
1989
|
-
elif np.isclose(width, height*2,
|
1989
|
+
elif np.isclose(width, height*2, rtol=1e-2, atol=1e-2):
|
1990
1990
|
radius = width/2
|
1991
1991
|
self.set_center([mm[1]-height, mm[2]])
|
1992
1992
|
logger.info("check for half machine")
|
@@ -2005,7 +2005,7 @@ class Geometry(object):
|
|
2005
2005
|
startangle=np.pi,
|
2006
2006
|
endangle=0.0)
|
2007
2007
|
|
2008
|
-
elif np.isclose(width*2, height,
|
2008
|
+
elif np.isclose(width*2, height, rtol=1e-2, atol=1e-2):
|
2009
2009
|
radius = width
|
2010
2010
|
logger.info("check for half machine")
|
2011
2011
|
self.set_center([mm[1], mm[3]-width])
|
@@ -2256,45 +2256,120 @@ class Geometry(object):
|
|
2256
2256
|
return center[0]
|
2257
2257
|
return None
|
2258
2258
|
|
2259
|
-
def
|
2259
|
+
def is_same_center(self, center_lst, center, rtol, atol):
|
2260
|
+
for c in center_lst:
|
2261
|
+
if points_are_close(c['center'], center['center'], rtol, atol):
|
2262
|
+
radius = center['radius'][0]
|
2263
|
+
if not radius in c['radius']:
|
2264
|
+
c['radius'].append(radius)
|
2265
|
+
c['count'] = c['count'] + 1
|
2266
|
+
return True
|
2267
|
+
return False
|
2268
|
+
|
2269
|
+
def get_center_with_x(self, center_lst, x):
|
2270
|
+
c_list = [c for c in center_lst
|
2271
|
+
if np.isclose(c['center'][0], x, rtol=self.rtol, atol=self.atol)]
|
2272
|
+
if not c_list:
|
2273
|
+
return None
|
2274
|
+
cy_list = [(c['center'][1], c) for c in c_list]
|
2275
|
+
cy_list.sort()
|
2276
|
+
y, c = cy_list[0]
|
2277
|
+
return c
|
2278
|
+
|
2279
|
+
def get_center_with_y(self, center_lst, y):
|
2280
|
+
c_list = [c for c in center_lst
|
2281
|
+
if np.isclose(c['center'][1], y, rtol=self.rtol, atol=self.atol)]
|
2282
|
+
if not c_list:
|
2283
|
+
return None
|
2284
|
+
cy_list = [(c['center'][0], c) for c in c_list]
|
2285
|
+
cy_list.sort()
|
2286
|
+
[logger.info("y=%s, c=%s", y, c) for y, c in cy_list]
|
2287
|
+
y, c = cy_list[0]
|
2288
|
+
return c
|
2289
|
+
|
2290
|
+
def get_center_arcs(self, mm):
|
2260
2291
|
logger.debug("begin of get_center_arcs")
|
2261
2292
|
center_list = []
|
2293
|
+
x_min, x_max, y_min, y_max = mm
|
2294
|
+
|
2295
|
+
def center_is_inside(c):
|
2296
|
+
tol = 0.1
|
2297
|
+
x, y = c
|
2298
|
+
if x-tol > x_min and \
|
2299
|
+
x+tol < x_max and \
|
2300
|
+
y-tol > y_min and \
|
2301
|
+
y+tol < y_max:
|
2302
|
+
return True
|
2303
|
+
return False
|
2304
|
+
|
2262
2305
|
circles = [e for e in self.elements() if is_Circle(e)]
|
2263
2306
|
logger.debug(" -- %s Circles", len(circles))
|
2264
2307
|
|
2265
2308
|
for e in circles:
|
2266
2309
|
center = (round(e.center[0], 3), round(e.center[1], 3))
|
2267
|
-
|
2268
|
-
|
2310
|
+
entry = {'center': center,
|
2311
|
+
'radius': [round(e.radius, 1)],
|
2312
|
+
'phi': e.get_angle_of_arc(),
|
2313
|
+
'dist': e.length(),
|
2314
|
+
'inside': center_is_inside(center),
|
2315
|
+
'count': 1}
|
2316
|
+
center_list.append(entry)
|
2269
2317
|
|
2270
2318
|
arcs = [e for e in self.elements() if is_Arc(e)]
|
2271
2319
|
logger.debug(" -- %s Arcs", len(arcs))
|
2272
2320
|
|
2273
2321
|
for e in arcs:
|
2274
2322
|
center = (round(e.center[0], 3), round(e.center[1], 3))
|
2275
|
-
|
2276
|
-
|
2277
|
-
|
2278
|
-
|
2279
|
-
|
2280
|
-
|
2281
|
-
|
2282
|
-
|
2323
|
+
entry = {'center': center,
|
2324
|
+
'radius': [round(e.radius, 1)],
|
2325
|
+
'phi': e.get_angle_of_arc(),
|
2326
|
+
'dist': e.length(),
|
2327
|
+
'inside': center_is_inside(center),
|
2328
|
+
'count': 1}
|
2329
|
+
if not self.is_same_center(center_list, entry, self.rtol, self.atol):
|
2330
|
+
center_list.append(entry)
|
2283
2331
|
|
2284
2332
|
center = None
|
2285
|
-
arc_list = [[
|
2333
|
+
arc_list = [[c['count'], len(c['radius']), c['phi'], n, c]
|
2334
|
+
for n, c in enumerate(center_list)]
|
2286
2335
|
arc_list.sort(reverse=True)
|
2287
2336
|
|
2288
|
-
|
2289
|
-
|
2290
|
-
center = c1[2]
|
2291
|
-
if len(arc_list) > 1:
|
2292
|
-
c2 = arc_list[1]
|
2293
|
-
if not c1[0] > c2[0]:
|
2294
|
-
center = None
|
2337
|
+
logger.debug("x min/max = %s/%s", x_min, x_max)
|
2338
|
+
logger.debug("y min/max = %s/%s", y_min, y_max)
|
2295
2339
|
|
2296
|
-
logger.debug("
|
2297
|
-
|
2340
|
+
[logger.debug("Arc %s", arc) for arc in arc_list]
|
2341
|
+
if not arc_list:
|
2342
|
+
logger.debug("end of get_center_arcs: no arcs")
|
2343
|
+
return None
|
2344
|
+
|
2345
|
+
cnt, cr1, p, n, c1 = arc_list[0]
|
2346
|
+
logger.debug("First Entry: %s", c1)
|
2347
|
+
center = c1['center']
|
2348
|
+
if len(arc_list) > 1:
|
2349
|
+
cnt, cr2, p, n, c2 = arc_list[1]
|
2350
|
+
logger.debug("Second Entry: %s", c2)
|
2351
|
+
if not cr1 > cr2:
|
2352
|
+
center = None
|
2353
|
+
|
2354
|
+
if center:
|
2355
|
+
logger.debug("end of get_center_arcs: -> %s", center)
|
2356
|
+
return center
|
2357
|
+
|
2358
|
+
c_entry = self.get_center_with_x(center_list, x_min)
|
2359
|
+
if c_entry:
|
2360
|
+
center = c_entry['center']
|
2361
|
+
if center[1] < y_min:
|
2362
|
+
logger.debug("end of get_center_arcs: x -> %s", center)
|
2363
|
+
return center
|
2364
|
+
c_entry = self.get_center_with_y(center_list, y_min)
|
2365
|
+
if c_entry:
|
2366
|
+
center = c_entry['center']
|
2367
|
+
if center[0] < x_min:
|
2368
|
+
logger.debug("end of get_center_arcs: y -> %s", center)
|
2369
|
+
return center
|
2370
|
+
|
2371
|
+
logger.debug("end of get_center_arcs: no center found")
|
2372
|
+
return None
|
2298
2373
|
|
2299
2374
|
def get_center_dim(self, mm):
|
2300
2375
|
return (round(mm[0], 4), round(mm[2], 4))
|
@@ -2305,7 +2380,9 @@ class Geometry(object):
|
|
2305
2380
|
return None
|
2306
2381
|
|
2307
2382
|
center = None
|
2308
|
-
|
2383
|
+
# Zuerst suchen wir anhand der Circle- und Arc-Segmente nach einem
|
2384
|
+
# möglichen Center-Punkt.
|
2385
|
+
center_arcs = self.get_center_arcs(mm)
|
2309
2386
|
|
2310
2387
|
if center_arcs:
|
2311
2388
|
center = center_arcs
|
@@ -2409,31 +2486,31 @@ class Geometry(object):
|
|
2409
2486
|
logger.debug("end check_airgap: return %s", len(area_id_list) > 1)
|
2410
2487
|
return len(area_id_list) > 1 # bad
|
2411
2488
|
|
2412
|
-
def is_border_line(self, center, startangle, endangle, e, atol):
|
2489
|
+
def is_border_line(self, center, startangle, endangle, e, rtol=1e-3, atol=1e-3):
|
2413
2490
|
if isinstance(e, Line):
|
2414
2491
|
if np.isclose(startangle, endangle):
|
2415
2492
|
return False # full
|
2416
2493
|
|
2417
2494
|
if points_are_close(center, e.p1):
|
2418
2495
|
angle_p2 = alpha_line(center, e.p2)
|
2419
|
-
if np.isclose(startangle, angle_p2,
|
2496
|
+
if np.isclose(startangle, angle_p2, rtol=rtol, atol=atol):
|
2420
2497
|
return True
|
2421
|
-
return np.isclose(endangle, angle_p2,
|
2498
|
+
return np.isclose(endangle, angle_p2, rtol=rtol, atol=atol)
|
2422
2499
|
|
2423
2500
|
if points_are_close(center, e.p2):
|
2424
2501
|
angle_p1 = alpha_line(center, e.p1)
|
2425
|
-
if np.isclose(startangle, angle_p1,
|
2502
|
+
if np.isclose(startangle, angle_p1, rtol=rtol, atol=atol):
|
2426
2503
|
return True
|
2427
|
-
return np.isclose(endangle, angle_p1,
|
2504
|
+
return np.isclose(endangle, angle_p1, rtol=rtol, atol=atol)
|
2428
2505
|
|
2429
2506
|
angle_p1 = alpha_line(center, e.p1)
|
2430
|
-
if np.isclose(startangle, angle_p1,
|
2507
|
+
if np.isclose(startangle, angle_p1, rtol=rtol, atol=atol):
|
2431
2508
|
angle_p2 = alpha_line(center, e.p2)
|
2432
|
-
return np.isclose(startangle, angle_p2,
|
2509
|
+
return np.isclose(startangle, angle_p2, rtol=rtol, atol=atol)
|
2433
2510
|
|
2434
|
-
if np.isclose(endangle, angle_p1,
|
2511
|
+
if np.isclose(endangle, angle_p1, rtol=rtol, atol=atol):
|
2435
2512
|
angle_p2 = alpha_line(center, e.p2)
|
2436
|
-
return np.isclose(endangle, angle_p2,
|
2513
|
+
return np.isclose(endangle, angle_p2, rtol=rtol, atol=atol)
|
2437
2514
|
return False
|
2438
2515
|
|
2439
2516
|
def get_gaplist(self, center):
|
@@ -2457,7 +2534,7 @@ class Geometry(object):
|
|
2457
2534
|
"""
|
2458
2535
|
gaplist = []
|
2459
2536
|
for e in self.elements(Shape):
|
2460
|
-
if not self.is_border_line(center, startangle, endangle, e, atol):
|
2537
|
+
if not self.is_border_line(center, startangle, endangle, e, atol=atol):
|
2461
2538
|
gaplist += [e.minmax_from_center(center)]
|
2462
2539
|
else:
|
2463
2540
|
min_r, max_r = e.minmax_from_center(center)
|
@@ -3259,7 +3336,7 @@ class Geometry(object):
|
|
3259
3336
|
max_size, max_w = windings_surface[0]
|
3260
3337
|
for sz, w in windings_surface[1:]:
|
3261
3338
|
logger.debug("winding size = %s", sz)
|
3262
|
-
if sz / max_size < 0.
|
3339
|
+
if sz / max_size < 0.70:
|
3263
3340
|
w.set_type(AREA.TYPE_AIR)
|
3264
3341
|
if sz / max_size < 0.2:
|
3265
3342
|
windings_found -= 1
|
femagtools/dxfsl/journal.py
CHANGED
femagtools/dxfsl/machine.py
CHANGED
@@ -135,6 +135,16 @@ class Machine(object):
|
|
135
135
|
self.geom.is_outer = True
|
136
136
|
self.geom.is_inner = False
|
137
137
|
|
138
|
+
def set_attributes(self,
|
139
|
+
kind="",
|
140
|
+
inner=False,
|
141
|
+
outer=False):
|
142
|
+
self.set_kind(kind)
|
143
|
+
if inner:
|
144
|
+
self.set_inner()
|
145
|
+
if outer:
|
146
|
+
self.set_outer()
|
147
|
+
|
138
148
|
def clear_cut_lines(self):
|
139
149
|
self.geom.clear_cut_lines()
|
140
150
|
if self.mirror_geom is not None:
|
@@ -635,9 +645,13 @@ class Machine(object):
|
|
635
645
|
parts = symmetry.find_symmetry() # temp solution
|
636
646
|
logger.debug(">>> Symmetry parts = %s <<<", parts)
|
637
647
|
|
638
|
-
if parts
|
639
|
-
|
640
|
-
|
648
|
+
if parts == 1:
|
649
|
+
# no slices, but ok
|
650
|
+
return False
|
651
|
+
|
652
|
+
found = (parts > 1)
|
653
|
+
|
654
|
+
if not found:
|
641
655
|
found = self.geom.find_symmetry(self.radius,
|
642
656
|
self.startangle,
|
643
657
|
self.endangle,
|
@@ -833,11 +847,11 @@ class Machine(object):
|
|
833
847
|
if dist_start > dist_end:
|
834
848
|
machine.mirror_all_areas(self.startangle)
|
835
849
|
machine.rotate_to(angle)
|
836
|
-
machine.geom.create_list_of_areas(delete=True)
|
837
850
|
machine.startangle -= angle
|
838
851
|
else:
|
839
852
|
machine.mirror_all_areas(self.endangle)
|
840
853
|
machine.endangle += angle
|
854
|
+
machine.geom.create_list_of_areas(delete=True)
|
841
855
|
machine.set_alfa_and_corners()
|
842
856
|
machine.part = machine.part_of_circle()
|
843
857
|
machine.geom.set_subregion_parameters(self.startangle,
|
@@ -907,23 +921,25 @@ class Machine(object):
|
|
907
921
|
first_thirdangle,
|
908
922
|
second_thirdangle)
|
909
923
|
machine_mirror_1.clear_cut_lines()
|
910
|
-
|
911
924
|
machine_mirror_1.repair_hull()
|
912
925
|
machine_mirror_1.set_alfa_and_corners()
|
926
|
+
if machine_mirror_1.geom.number_of_edges() < 2: # very bad
|
927
|
+
logger.debug("end get_third_symmetry_mirror: no remaining elements")
|
928
|
+
return None
|
913
929
|
if not machine_mirror_1.check_symmetry_graph(0.001, 0.05):
|
914
930
|
logger.debug("end get_third_symmetry_mirror: no mirror first third")
|
915
931
|
return None
|
916
932
|
|
917
933
|
if plt:
|
918
934
|
plt.render_elements(machine_mirror_1.geom, Shape,
|
919
|
-
title="Part",
|
935
|
+
title="Part 1",
|
920
936
|
show=True,
|
921
937
|
with_corners=False,
|
922
938
|
with_nodes=False,
|
923
939
|
neighbors=True)
|
924
940
|
|
925
941
|
plt.render_elements(machine_mirror_1.mirror_geom, Shape,
|
926
|
-
title="Counterpart",
|
942
|
+
title="Counterpart 1",
|
927
943
|
show=True,
|
928
944
|
with_corners=False,
|
929
945
|
with_nodes=False,
|
@@ -935,10 +951,28 @@ class Machine(object):
|
|
935
951
|
machine_mirror_2.clear_cut_lines()
|
936
952
|
machine_mirror_2.repair_hull()
|
937
953
|
machine_mirror_2.set_alfa_and_corners()
|
954
|
+
if machine_mirror_2.geom.number_of_edges() < 2: # very bad
|
955
|
+
logger.debug("end get_third_symmetry_mirror: no remaining elements")
|
956
|
+
return None
|
938
957
|
if not machine_mirror_2.check_symmetry_graph(0.001, 0.05):
|
939
958
|
logger.debug("end get_third_symmetry_mirror: no mirror second third")
|
940
959
|
return None
|
941
960
|
|
961
|
+
if plt:
|
962
|
+
plt.render_elements(machine_mirror_2.geom, Shape,
|
963
|
+
title="Part 2",
|
964
|
+
show=True,
|
965
|
+
with_corners=False,
|
966
|
+
with_nodes=False,
|
967
|
+
neighbors=True)
|
968
|
+
|
969
|
+
plt.render_elements(machine_mirror_2.mirror_geom, Shape,
|
970
|
+
title="Counterpart 2",
|
971
|
+
show=True,
|
972
|
+
with_corners=False,
|
973
|
+
with_nodes=False,
|
974
|
+
neighbors=True)
|
975
|
+
|
942
976
|
machine_mirror_1.previous_machine = self
|
943
977
|
logger.debug("end get_third_symmetry_mirror: ok")
|
944
978
|
return machine_mirror_1
|
@@ -992,6 +1026,9 @@ class Machine(object):
|
|
992
1026
|
with_nodes=False,
|
993
1027
|
neighbors=True)
|
994
1028
|
|
1029
|
+
if machine_mirror.geom.number_of_edges() < 2: # very bad
|
1030
|
+
logger.debug("end get_symmetry_mirror: no remaining elements")
|
1031
|
+
return None
|
995
1032
|
if machine_mirror.check_symmetry_graph(0.001, 0.05):
|
996
1033
|
machine_mirror.previous_machine = self
|
997
1034
|
machine_mirror.rotate_to(0.0)
|
femagtools/dxfsl/shape.py
CHANGED
@@ -467,6 +467,10 @@ class Circle(Shape):
|
|
467
467
|
r0 = np.linalg.norm(self.center)
|
468
468
|
return max(abs(r-r0-self.radius), abs(r-r0+self.radius))
|
469
469
|
|
470
|
+
def length(self):
|
471
|
+
"""returns length of this circle"""
|
472
|
+
return self.radius*2*np.pi
|
473
|
+
|
470
474
|
def overlapping_shape(self, e, rtol=1e-03, atol=1e-03):
|
471
475
|
if not (isinstance(e, Arc) or isinstance(e, Circle)):
|
472
476
|
# end overlapping_shape: Circle (not Arc or Circle)
|
femagtools/dxfsl/symmetry.py
CHANGED
@@ -102,6 +102,7 @@ class Symmetry(object):
|
|
102
102
|
a.get_mid_angle(self.geom.center)))
|
103
103
|
|
104
104
|
def area_list_entry(self, a):
|
105
|
+
a.set_symmetry_parameter(self.geom.center)
|
105
106
|
return (round(a.get_alpha(self.geom.center), 3),
|
106
107
|
round(a.min_dist, 1),
|
107
108
|
round(a.height, 1),
|
@@ -119,24 +120,47 @@ class Symmetry(object):
|
|
119
120
|
areas.sort(reverse=True)
|
120
121
|
return areas
|
121
122
|
|
123
|
+
def get_equal_areas(self, areas):
|
124
|
+
return
|
125
|
+
|
122
126
|
def build_results(self, areas):
|
127
|
+
logger.debug("begin of build_results with %s areas", len(areas))
|
128
|
+
[logger.debug("#%s: alpha=%s, min=%s, max=%s",
|
129
|
+
a.get_id(), alpha, a.min_angle, a.max_angle) for
|
130
|
+
alpha, dist, h, mid, a in areas]
|
131
|
+
|
123
132
|
a0_alpha, a0_min_dist, a0_height, a0_mid_angle, a0 = areas[0]
|
124
133
|
equal_areas = [(a0_mid_angle, a0)]
|
125
134
|
check_rslt = []
|
126
135
|
for a1_alpha, a1_min_dist, a1_height, a1_mid_angle, a1 in areas[1:]:
|
127
|
-
if self.equal_area(a0_min_dist, a0_height, a0_alpha,
|
128
|
-
|
129
|
-
|
136
|
+
if (self.equal_area(a0_min_dist, a0_height, a0_alpha,
|
137
|
+
a1_min_dist, a1_height, a1_alpha,
|
138
|
+
rtol=0.001, atol=0.05)):
|
130
139
|
a0_min_dist = (a0_min_dist + a1_min_dist) / 2
|
131
140
|
a0_height = (a0_height + a1_height) / 2
|
132
141
|
a0_alpha = (a0_alpha + a1_alpha) / 2
|
133
142
|
equal_areas.append((a1_mid_angle, a1))
|
134
143
|
else:
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
144
|
+
# alpha Wechsel
|
145
|
+
id_list = []
|
146
|
+
for i in range(len(equal_areas)):
|
147
|
+
mid_angle0, area0 = equal_areas[i]
|
148
|
+
if area0.get_id() in id_list:
|
149
|
+
continue
|
150
|
+
equal_areas_check = [(mid_angle0, area0)]
|
151
|
+
for mid_angle1, area1 in equal_areas[i+1:]:
|
152
|
+
if area1.get_id() in id_list:
|
153
|
+
continue
|
154
|
+
if area0.is_symmetry_equal(area1):
|
155
|
+
equal_areas_check.append((mid_angle1, area1))
|
156
|
+
id_list.append(area1.get_id())
|
157
|
+
|
158
|
+
rslt = self.check_delta(equal_areas_check)
|
159
|
+
areasize = a0.area_size()
|
160
|
+
rslt['area'] = a0
|
161
|
+
rslt['areasize'] = areasize
|
162
|
+
check_rslt.append((areasize, rslt))
|
163
|
+
|
140
164
|
equal_areas = [(a1_mid_angle, a1)]
|
141
165
|
a0_min_dist = a1_min_dist
|
142
166
|
a0_height = a1_height
|
@@ -148,12 +172,14 @@ class Symmetry(object):
|
|
148
172
|
rslt['area'] = a0
|
149
173
|
rslt['areasize'] = areasize
|
150
174
|
check_rslt.append((areasize, rslt))
|
175
|
+
logger.debug("end of build_results")
|
151
176
|
return check_rslt
|
152
177
|
|
153
178
|
def get_winding_symmetry(self, inside=False):
|
154
179
|
if inside:
|
155
180
|
areas = [self.area_list_entry(a) for a in self.geom.list_of_areas()
|
156
181
|
if not a.close_to_ag]
|
182
|
+
areas.sort(reverse=True)
|
157
183
|
else:
|
158
184
|
areas = self.build_area_list((AREA.TYPE_WINDINGS,))
|
159
185
|
|
@@ -228,6 +254,7 @@ class Symmetry(object):
|
|
228
254
|
return 0
|
229
255
|
|
230
256
|
check_rslt = self.build_results(areas)
|
257
|
+
logger.debug("%s results available", len(check_rslt))
|
231
258
|
|
232
259
|
parts, start_delta = self.get_symmetry_parts(check_rslt)
|
233
260
|
if parts < 2:
|
@@ -248,6 +275,7 @@ class Symmetry(object):
|
|
248
275
|
result = {'areas': len(area_list),
|
249
276
|
'startdelta': 0.0,
|
250
277
|
'slices': None}
|
278
|
+
result['area_id_list'] = [a.get_id() for m, a in area_list]
|
251
279
|
if not area_list:
|
252
280
|
logger.debug("end of check_delta: no areas")
|
253
281
|
return result
|
@@ -645,6 +673,9 @@ class Symmetry(object):
|
|
645
673
|
m1 = m2
|
646
674
|
d1 = d2
|
647
675
|
|
676
|
+
if not mid_list:
|
677
|
+
return None
|
678
|
+
|
648
679
|
logger.debug("New Mids: %s", mid_list)
|
649
680
|
delta = positive_angle(mid_list[0] * 2)
|
650
681
|
delta_list = [delta]
|
@@ -692,6 +723,41 @@ class Symmetry(object):
|
|
692
723
|
logger.debug("end check_first_last_difference => %s", n1 + 1)
|
693
724
|
return n1 + 1
|
694
725
|
|
726
|
+
def concatenate_results(self, check_rslt):
|
727
|
+
if len(check_rslt) < 2:
|
728
|
+
return check_rslt
|
729
|
+
# ----------
|
730
|
+
def get_slices(rslt):
|
731
|
+
if rslt['slices'] is None:
|
732
|
+
return 0
|
733
|
+
if rslt.get('startdelta', 0.0) != 0.0:
|
734
|
+
return 0
|
735
|
+
if rslt.get('halfslice', None) is not None:
|
736
|
+
return 0
|
737
|
+
return rslt['slices']
|
738
|
+
# ------
|
739
|
+
new_rslt = []
|
740
|
+
size1, n1, rslt1 = check_rslt[0]
|
741
|
+
slices1 = get_slices(rslt1)
|
742
|
+
for size2, n2, rslt2 in check_rslt[1:]:
|
743
|
+
slices2 = get_slices(rslt2)
|
744
|
+
if slices1 > 0 and \
|
745
|
+
slices1 == slices2 and \
|
746
|
+
np.isclose(size1, size2, rtol=1e-01, atol=1e-01) and \
|
747
|
+
(rslt1.get('delta_corr', 0.0) == 0.0 or \
|
748
|
+
rslt2.get('delta_corr', 0.0) == 0.0):
|
749
|
+
# concatenate
|
750
|
+
rslt1['slices'] = None
|
751
|
+
rslt2['delta_corr'] = 0.0
|
752
|
+
rslt2['areas'] = rslt2['areas'] + rslt1['areas']
|
753
|
+
logger.debug("concatenate results(size %s)", size1)
|
754
|
+
else:
|
755
|
+
new_rslt.append((size1, n1, rslt1))
|
756
|
+
slices1, size1, n1, rslt1 = (slices2, size2, n2, rslt2)
|
757
|
+
|
758
|
+
new_rslt.append((size1, n1, rslt1))
|
759
|
+
return new_rslt
|
760
|
+
|
695
761
|
def get_symmetry_parts(self, check_rslt):
|
696
762
|
max_size = 0
|
697
763
|
max_areas = 0
|
@@ -700,10 +766,11 @@ class Symmetry(object):
|
|
700
766
|
self.delta_angle_corr = None
|
701
767
|
unsure_sym = False
|
702
768
|
|
703
|
-
check_rslt = [(size, n, rslt) for n, (size, rslt) in enumerate(check_rslt)
|
769
|
+
check_rslt = [(size, n, rslt) for n, (size, rslt) in enumerate(check_rslt)
|
770
|
+
if rslt['slices'] is not None]
|
704
771
|
check_rslt.sort(reverse=True)
|
705
|
-
|
706
|
-
|
772
|
+
check_rslt = self.concatenate_results(check_rslt)
|
773
|
+
[logger.debug("Result #%s: %s, %s", n, size, rslt) for size, n, rslt in check_rslt]
|
707
774
|
|
708
775
|
rtol = 1e-3
|
709
776
|
atol = 1e-2
|
@@ -720,40 +787,46 @@ class Symmetry(object):
|
|
720
787
|
for size, n, rslt in check_rslt:
|
721
788
|
areas = rslt['areas']
|
722
789
|
slices = rslt['slices']
|
790
|
+
if slices is None:
|
791
|
+
continue
|
792
|
+
|
723
793
|
size = rslt['areasize']
|
724
794
|
angle_corr = rslt.get('delta_corr', 0.0)
|
725
795
|
|
726
796
|
if rslt.get('halfslice', 0) == 1:
|
727
797
|
halfslice.append(rslt)
|
728
798
|
|
729
|
-
if slices
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
738
|
-
|
739
|
-
|
740
|
-
|
741
|
-
|
742
|
-
|
743
|
-
without_angle_corr += areas * size
|
744
|
-
else:
|
745
|
-
with_angle_corr += areas * size
|
799
|
+
if slices > 0:
|
800
|
+
max_size = max(max_size, size)
|
801
|
+
max_areas = max(max_areas, areas)
|
802
|
+
max_slices = max(max_slices, slices)
|
803
|
+
missing_middles += rslt.get('missing_middles', [])
|
804
|
+
area = rslt['area']
|
805
|
+
if not (np.isclose(area.min_dist,
|
806
|
+
self.geom.min_radius,
|
807
|
+
rtol=1e-4, atol=1e-3) and \
|
808
|
+
np.isclose(area.max_dist,
|
809
|
+
self.geom.max_radius,
|
810
|
+
rtol=1e-4, atol=1e-3)):
|
811
|
+
if rslt.get('delta_corr', 0.0) == 0.0:
|
812
|
+
without_angle_corr += areas * size
|
746
813
|
else:
|
747
|
-
|
814
|
+
with_angle_corr += areas * size
|
815
|
+
else:
|
816
|
+
maybe_angle_korr += areas * size
|
817
|
+
|
748
818
|
logger.debug("max size: %s, max areas: %s", max_size, max_areas)
|
819
|
+
logger.debug("Angle-Corrections: %s Yes, %s No, %s Maybe",
|
820
|
+
with_angle_corr,
|
821
|
+
without_angle_corr,
|
822
|
+
maybe_angle_korr)
|
749
823
|
|
750
|
-
logger.debug("Angle-Corrections: %s Yes, %s No",
|
751
|
-
with_angle_corr, without_angle_corr)
|
752
824
|
if np.isclose(with_angle_corr, without_angle_corr):
|
753
825
|
with_angle_corr = (maybe_angle_korr > 0)
|
754
826
|
else:
|
755
827
|
with_angle_corr = (with_angle_corr > without_angle_corr)
|
756
828
|
|
829
|
+
# -------------------------
|
757
830
|
def get_halfslice_counterpart(rslt):
|
758
831
|
if rslt.get('halfslice', 0) != 2:
|
759
832
|
return None
|
@@ -768,7 +841,7 @@ class Symmetry(object):
|
|
768
841
|
np.isclose(alpha1, alpha2, rtol=rtol, atol=atol):
|
769
842
|
return half
|
770
843
|
return None
|
771
|
-
|
844
|
+
# -----------
|
772
845
|
if halfslice:
|
773
846
|
logger.debug("%s halfslice [1] found", len(halfslice))
|
774
847
|
|