femagtools 1.8.1__py3-none-any.whl → 1.8.3__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/dxfsl/area.py +110 -1
- femagtools/dxfsl/areabuilder.py +93 -45
- femagtools/dxfsl/conv.py +5 -0
- femagtools/dxfsl/converter.py +85 -27
- femagtools/dxfsl/fslrenderer.py +5 -4
- femagtools/dxfsl/functions.py +14 -6
- femagtools/dxfsl/geom.py +135 -149
- femagtools/dxfsl/journal.py +1 -1
- femagtools/dxfsl/machine.py +161 -9
- femagtools/dxfsl/shape.py +46 -1
- femagtools/dxfsl/svgparser.py +1 -1
- femagtools/dxfsl/symmetry.py +143 -38
- femagtools/femag.py +64 -61
- femagtools/fsl.py +15 -12
- femagtools/isa7.py +3 -2
- femagtools/machine/__init__.py +5 -4
- femagtools/machine/afpm.py +79 -33
- femagtools/machine/effloss.py +29 -18
- femagtools/machine/sizing.py +192 -13
- femagtools/machine/sm.py +34 -36
- femagtools/machine/utils.py +2 -2
- femagtools/mcv.py +58 -29
- femagtools/model.py +4 -3
- femagtools/multiproc.py +79 -80
- femagtools/parstudy.py +11 -5
- femagtools/plot/nc.py +2 -2
- 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/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/zmq.py +213 -0
- {femagtools-1.8.1.dist-info → femagtools-1.8.3.dist-info}/METADATA +3 -3
- {femagtools-1.8.1.dist-info → femagtools-1.8.3.dist-info}/RECORD +49 -47
- {femagtools-1.8.1.dist-info → femagtools-1.8.3.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 +21 -15
- {femagtools-1.8.1.dist-info → femagtools-1.8.3.dist-info}/LICENSE +0 -0
- {femagtools-1.8.1.dist-info → femagtools-1.8.3.dist-info}/entry_points.txt +0 -0
- {femagtools-1.8.1.dist-info → femagtools-1.8.3.dist-info}/top_level.txt +0 -0
femagtools/dxfsl/machine.py
CHANGED
@@ -247,16 +247,21 @@ class Machine(object):
|
|
247
247
|
startangle=self.startangle,
|
248
248
|
endangle=self.endangle)
|
249
249
|
|
250
|
-
def
|
250
|
+
def clone(self):
|
251
251
|
clone = self.geom.copy_shape(self.radius,
|
252
252
|
0.0, 2*np.pi,
|
253
|
-
0.0,
|
254
|
-
|
253
|
+
0.0,
|
254
|
+
self.radius+9999,
|
255
|
+
concatenate=False,
|
256
|
+
connect=False)
|
255
257
|
clone.kind = self.geom.kind
|
256
258
|
clone.sym_part = self.geom.sym_part
|
257
259
|
clone.sym_counterpart = self.geom.sym_counterpart
|
258
260
|
clone.alfa = self.geom.alfa
|
259
|
-
|
261
|
+
return Machine(clone,
|
262
|
+
radius = self.radius,
|
263
|
+
startangle=self.startangle,
|
264
|
+
endangle=self.endangle)
|
260
265
|
|
261
266
|
def copy_mirror(self, startangle, midangle, endangle):
|
262
267
|
logger.debug("begin of copy_mirror")
|
@@ -532,7 +537,7 @@ class Machine(object):
|
|
532
537
|
logger.debug('begin repair_hull_geom (%s, %s)', startangle, endangle)
|
533
538
|
|
534
539
|
rtol = 1e-3
|
535
|
-
atol = 1e-
|
540
|
+
atol = 1e-3
|
536
541
|
c_corner = Corner(self.center, self.center)
|
537
542
|
start_c_added, start_corners = geom.get_corner_list(self.center, startangle,
|
538
543
|
rtol=rtol, atol=atol)
|
@@ -590,8 +595,34 @@ class Machine(object):
|
|
590
595
|
return w
|
591
596
|
|
592
597
|
def slot_area(self):
|
593
|
-
|
594
|
-
|
598
|
+
return self.geom.area_size_of_type(AREA.TYPE_WINDINGS)
|
599
|
+
|
600
|
+
def get_winding_symmetry(self, inside=False):
|
601
|
+
logger.debug("begin of get_winding_symmetry")
|
602
|
+
symmetry = Symmetry(geom=self.geom,
|
603
|
+
startangle=self.startangle,
|
604
|
+
endangle=self.endangle)
|
605
|
+
parts = symmetry.get_winding_symmetry(inside=inside)
|
606
|
+
logger.debug("end of get_winding_symmetry (parts=%s)", parts)
|
607
|
+
return parts
|
608
|
+
|
609
|
+
def get_magnet_symmetry(self):
|
610
|
+
logger.debug("begin of get_magnet_symmetry")
|
611
|
+
symmetry = Symmetry(geom=self.geom,
|
612
|
+
startangle=self.startangle,
|
613
|
+
endangle=self.endangle)
|
614
|
+
parts = symmetry.get_magnet_symmetry()
|
615
|
+
logger.debug("end of get_magnet_symmetry (parts=%s)", parts)
|
616
|
+
return parts
|
617
|
+
|
618
|
+
def get_symmetry(self):
|
619
|
+
logger.debug("begin of get_symmetry")
|
620
|
+
symmetry = Symmetry(geom=self.geom,
|
621
|
+
startangle=self.startangle,
|
622
|
+
endangle=self.endangle)
|
623
|
+
parts = symmetry.find_symmetry()
|
624
|
+
logger.debug("end of get_symmetry (parts=%s)", parts)
|
625
|
+
return parts
|
595
626
|
|
596
627
|
def find_symmetry(self, sym_tolerance, is_inner, is_outer, plt):
|
597
628
|
logger.debug("begin of find_symmetry")
|
@@ -761,6 +792,97 @@ class Machine(object):
|
|
761
792
|
self.geom.symmetry_endangle()))
|
762
793
|
return machine_slice
|
763
794
|
|
795
|
+
def get_forced_winding_slice(self):
|
796
|
+
logger.debug("get_forced_winding_slice()")
|
797
|
+
if not self.geom.is_outer:
|
798
|
+
return None
|
799
|
+
|
800
|
+
areas = len(self.geom.area_list)
|
801
|
+
winding_areas = self.geom.num_of_windings()
|
802
|
+
iron_areas = self.geom.num_of_irons()
|
803
|
+
air_areas = self.geom.num_areas_of_type((AREA.TYPE_AIR,))
|
804
|
+
|
805
|
+
if not (winding_areas + iron_areas + air_areas == areas):
|
806
|
+
logger.warning("Warning: strange areas in stator")
|
807
|
+
|
808
|
+
if winding_areas == 0:
|
809
|
+
return self.get_possible_windings()
|
810
|
+
|
811
|
+
if winding_areas < 2:
|
812
|
+
return None # nothing to do
|
813
|
+
parts = self.get_winding_symmetry()
|
814
|
+
if parts < 2:
|
815
|
+
return None # nothing to do
|
816
|
+
return self.get_symmetry_slice()
|
817
|
+
|
818
|
+
def get_possible_windings(self, EESM=False, single=False):
|
819
|
+
if not self.geom.is_outer:
|
820
|
+
return None
|
821
|
+
|
822
|
+
machine = self.clone()
|
823
|
+
machine.repair_hull()
|
824
|
+
machine.set_alfa_and_corners()
|
825
|
+
machine.geom.set_subregion_parameters(self.startangle,
|
826
|
+
self.endangle)
|
827
|
+
machine.geom.looking_for_corners()
|
828
|
+
dist_start = machine.geom.dist_start_min_corner()
|
829
|
+
dist_end = machine.geom.dist_end_min_corner()
|
830
|
+
|
831
|
+
if not np.isclose(dist_start, dist_end, rtol=1e-3, atol=1e-3):
|
832
|
+
angle = machine.geom.alfa
|
833
|
+
if dist_start > dist_end:
|
834
|
+
machine.mirror_all_areas(self.startangle)
|
835
|
+
machine.rotate_to(angle)
|
836
|
+
machine.geom.create_list_of_areas(delete=True)
|
837
|
+
machine.startangle -= angle
|
838
|
+
else:
|
839
|
+
machine.mirror_all_areas(self.endangle)
|
840
|
+
machine.endangle += angle
|
841
|
+
machine.set_alfa_and_corners()
|
842
|
+
machine.part = machine.part_of_circle()
|
843
|
+
machine.geom.set_subregion_parameters(self.startangle,
|
844
|
+
self.endangle)
|
845
|
+
machine.geom.looking_for_corners()
|
846
|
+
|
847
|
+
if machine.geom.close_outer_winding_areas():
|
848
|
+
machine.geom.create_list_of_areas(delete=True)
|
849
|
+
machine.geom.set_subregion_parameters(self.startangle,
|
850
|
+
self.endangle)
|
851
|
+
machine.geom.looking_for_corners()
|
852
|
+
parts = machine.get_winding_symmetry(inside=True)
|
853
|
+
|
854
|
+
if parts == 1:
|
855
|
+
return machine
|
856
|
+
if parts > 1:
|
857
|
+
return machine.get_symmetry_slice()
|
858
|
+
|
859
|
+
return machine
|
860
|
+
|
861
|
+
def get_forced_magnet_slice(self):
|
862
|
+
logger.debug("get_forced_magnet_slice()")
|
863
|
+
areas = len(self.geom.area_list)
|
864
|
+
magnet_areas = self.geom.num_of_magnets()
|
865
|
+
iron_areas = self.geom.num_of_irons()
|
866
|
+
air_areas = self.geom.num_areas_of_type((AREA.TYPE_AIR,))
|
867
|
+
|
868
|
+
if magnet_areas < 2:
|
869
|
+
return None # nothing to do
|
870
|
+
parts = self.get_magnet_symmetry()
|
871
|
+
|
872
|
+
if parts < 2:
|
873
|
+
return None # nothing to do
|
874
|
+
slice = self.get_symmetry_slice()
|
875
|
+
match = slice.geom.min_max_corners_match()
|
876
|
+
while parts > 1 and not match:
|
877
|
+
parts = parts - 1
|
878
|
+
self.geom.rotate_symmetry_parameters()
|
879
|
+
slice = self.get_symmetry_slice()
|
880
|
+
match = slice.geom.min_max_corners_match()
|
881
|
+
if match:
|
882
|
+
slice.geom.set_rotor()
|
883
|
+
return slice
|
884
|
+
return None
|
885
|
+
|
764
886
|
def get_forced_symmetry(self, part):
|
765
887
|
logger.debug("begin get_forced_symmetry")
|
766
888
|
if not self.is_full():
|
@@ -1041,6 +1163,13 @@ class Machine(object):
|
|
1041
1163
|
|
1042
1164
|
def sync_with_counterpart(self, cp_machine):
|
1043
1165
|
logger.debug("sync_with_counterpart")
|
1166
|
+
|
1167
|
+
def not_tiny_areas(geom):
|
1168
|
+
sz_list = [a.area_size() for a in geom.list_of_areas()]
|
1169
|
+
max_sz = max(sz_list)
|
1170
|
+
large_sz_list = [sz for sz in sz_list if sz > max_sz * 0.005]
|
1171
|
+
return len(large_sz_list)
|
1172
|
+
|
1044
1173
|
self.geom.sym_counterpart = cp_machine.get_symmetry_part()
|
1045
1174
|
self.geom.sym_part = self.get_symmetry_part()
|
1046
1175
|
logger.debug("part/sym-part: self=%s/%s, cp=%s/%s",
|
@@ -1049,6 +1178,14 @@ class Machine(object):
|
|
1049
1178
|
cp_machine.geom.sym_counterpart = self.get_symmetry_part()
|
1050
1179
|
cp_machine.geom.sym_part = cp_machine.get_symmetry_part()
|
1051
1180
|
|
1181
|
+
if not_tiny_areas(self.geom) == 1:
|
1182
|
+
if not_tiny_areas(cp_machine.geom) > 1:
|
1183
|
+
self.geom.force_to_be_stator()
|
1184
|
+
cp_machine.geom.force_to_be_rotor()
|
1185
|
+
elif not_tiny_areas(cp_machine.geom) == 1:
|
1186
|
+
self.geom.force_to_be_rotor()
|
1187
|
+
cp_machine.geom.force_to_be_stator()
|
1188
|
+
|
1052
1189
|
def search_subregions(self, EESM, single=False):
|
1053
1190
|
logger.debug("Search subregions")
|
1054
1191
|
self.geom.search_subregions(self.startangle,
|
@@ -1073,8 +1210,7 @@ class Machine(object):
|
|
1073
1210
|
|
1074
1211
|
def rebuild_subregions(self, EESM, single=False):
|
1075
1212
|
logger.debug("Rebuild subregions")
|
1076
|
-
self.geom.
|
1077
|
-
self.geom.area_list = []
|
1213
|
+
self.geom.create_list_of_areas(delete=True)
|
1078
1214
|
self.geom.search_subregions(self.startangle,
|
1079
1215
|
self.endangle,
|
1080
1216
|
EESM,
|
@@ -1142,6 +1278,11 @@ class Machine(object):
|
|
1142
1278
|
self.endangle)
|
1143
1279
|
return self.geom.windings_in_the_middle(midangle)
|
1144
1280
|
|
1281
|
+
def has_magnets_in_the_middle(self):
|
1282
|
+
midangle = middle_angle(self.startangle,
|
1283
|
+
self.endangle)
|
1284
|
+
return self.geom.magnets_in_the_middle(midangle)
|
1285
|
+
|
1145
1286
|
def create_mirror_lines_outside_windings(self):
|
1146
1287
|
logger.debug("create_mirror_lines_outside_windings")
|
1147
1288
|
|
@@ -1272,3 +1413,14 @@ class Machine(object):
|
|
1272
1413
|
self.clear_cut_lines()
|
1273
1414
|
self.repair_hull()
|
1274
1415
|
self.set_alfa_and_corners()
|
1416
|
+
|
1417
|
+
def mirror_all_areas(self, mirror_angle):
|
1418
|
+
self.geom.mirror_all_areas(mirror_angle)
|
1419
|
+
|
1420
|
+
def check_airgap_connecting_nodes(self, m_outer):
|
1421
|
+
logger.info("check_airgap_connecting_nodes")
|
1422
|
+
assert(self.geom.is_inner)
|
1423
|
+
assert(m_outer.geom.is_outer)
|
1424
|
+
self.geom.check_airgap_connecting_nodes(m_outer.geom,
|
1425
|
+
self.startangle,
|
1426
|
+
self.endangle)
|
femagtools/dxfsl/shape.py
CHANGED
@@ -11,7 +11,7 @@ from __future__ import print_function
|
|
11
11
|
import numpy as np
|
12
12
|
import logging
|
13
13
|
from .functions import less_equal, greater_equal
|
14
|
-
from .functions import distance, line_m, line_n
|
14
|
+
from .functions import distance, line_m, line_n, mirror_point
|
15
15
|
from .functions import point, points_are_close, points_on_arc
|
16
16
|
from .functions import alpha_line, alpha_angle, alpha_triangle
|
17
17
|
from .functions import normalise_angle, min_angle, max_angle, get_angle_of_arc
|
@@ -54,6 +54,9 @@ class Shape(object):
|
|
54
54
|
def classname(self):
|
55
55
|
return "Shape"
|
56
56
|
|
57
|
+
def clone(self):
|
58
|
+
return None
|
59
|
+
|
57
60
|
def set_my_color(self, color):
|
58
61
|
self.my_color = color
|
59
62
|
|
@@ -314,6 +317,32 @@ class Shape(object):
|
|
314
317
|
def is_near(self, n):
|
315
318
|
return False
|
316
319
|
|
320
|
+
def mirror_shape(self, geom_center, axis_m, axis_n):
|
321
|
+
n2 = mirror_point(self.start(), geom_center, axis_m, axis_n)
|
322
|
+
n1 = mirror_point(self.end(), geom_center, axis_m, axis_n)
|
323
|
+
|
324
|
+
el = None
|
325
|
+
if isinstance(self, Line):
|
326
|
+
el = Line(Element(start=n1, end=n2))
|
327
|
+
|
328
|
+
elif isinstance(self, Arc):
|
329
|
+
c = mirror_point(self.center, geom_center, axis_m, axis_n)
|
330
|
+
alpha1 = alpha_line(c, n1)
|
331
|
+
alpha2 = alpha_line(c, n2)
|
332
|
+
el = Arc(Element(center=c,
|
333
|
+
radius=self.radius,
|
334
|
+
start_angle=alpha1*180/np.pi,
|
335
|
+
end_angle=alpha2*180/np.pi))
|
336
|
+
|
337
|
+
elif isinstance(self, Circle):
|
338
|
+
c = mirror_point(self.center, geom_center, axis_m, axis_n)
|
339
|
+
el = Circle(Element(center=c,
|
340
|
+
radius=self.radius))
|
341
|
+
|
342
|
+
if el:
|
343
|
+
el.copy_attributes(self)
|
344
|
+
return el
|
345
|
+
|
317
346
|
def print_nodes(self):
|
318
347
|
return " n1={}/n2={}".format(self.n1, self.n2)
|
319
348
|
|
@@ -354,6 +383,10 @@ class Circle(Shape):
|
|
354
383
|
def classname(self):
|
355
384
|
return "Circle"
|
356
385
|
|
386
|
+
def clone(self):
|
387
|
+
return Circle(Element(center=self.center,
|
388
|
+
radius=self.radius))
|
389
|
+
|
357
390
|
def render(self, renderer, color='blue', with_nodes=False):
|
358
391
|
tmp_color = self.get_my_color()
|
359
392
|
if not tmp_color:
|
@@ -742,6 +775,14 @@ class Arc(Circle):
|
|
742
775
|
def classname(self):
|
743
776
|
return "Arc"
|
744
777
|
|
778
|
+
def clone(self):
|
779
|
+
alpha_start = alpha_line(self.center, self.p1)
|
780
|
+
alpha_end = alpha_line(self.center, self.p2)
|
781
|
+
return Arc(Element(center=self.center,
|
782
|
+
radius=self.radius,
|
783
|
+
start_angle=alpha_start*180/np.pi,
|
784
|
+
end_angle=alpha_end*180/np.pi))
|
785
|
+
|
745
786
|
def render(self, renderer, color='blue', with_nodes=False):
|
746
787
|
tmp_color = self.get_my_color()
|
747
788
|
if not tmp_color:
|
@@ -1285,6 +1326,10 @@ class Line(Shape):
|
|
1285
1326
|
def classname(self):
|
1286
1327
|
return "Line"
|
1287
1328
|
|
1329
|
+
def clone(self):
|
1330
|
+
return Line(Element(start=self.p1,
|
1331
|
+
end=self.p2))
|
1332
|
+
|
1288
1333
|
def render(self, renderer, color='blue', with_nodes=False):
|
1289
1334
|
tmp_color = self.get_my_color()
|
1290
1335
|
if not tmp_color:
|
femagtools/dxfsl/svgparser.py
CHANGED
@@ -106,7 +106,7 @@ def svgshapes(svgfile):
|
|
106
106
|
for p in svg.findall(".//{http://www.w3.org/2000/svg}path"):
|
107
107
|
m = bcolor.search(p.get('style'))
|
108
108
|
if m:
|
109
|
-
logger.
|
109
|
+
logger.debug("subregion %d: %s", sr, m.groups()[0])
|
110
110
|
yield from get_shapes(p.get('d'))
|
111
111
|
sr += 1
|
112
112
|
for p in svg.findall(".//{http://www.w3.org/2000/svg}line"):
|
femagtools/dxfsl/symmetry.py
CHANGED
@@ -12,6 +12,7 @@ import logging
|
|
12
12
|
import sys
|
13
13
|
from femagtools.dxfsl.shape import Element, Line
|
14
14
|
from femagtools.dxfsl.area import Area
|
15
|
+
import femagtools.dxfsl.area as AREA
|
15
16
|
from femagtools.dxfsl.functions import alpha_angle, positive_angle, is_same_angle
|
16
17
|
from femagtools.dxfsl.functions import min_angle, max_angle, gcd, point
|
17
18
|
from femagtools.dxfsl.functions import less_equal, less, points_are_close
|
@@ -100,41 +101,58 @@ class Symmetry(object):
|
|
100
101
|
return positive_angle(alpha_angle(self.startangle,
|
101
102
|
a.get_mid_angle(self.geom.center)))
|
102
103
|
|
103
|
-
def
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
104
|
+
def area_list_entry(self, a):
|
105
|
+
a.set_symmetry_parameter(self.geom.center)
|
106
|
+
return (round(a.get_alpha(self.geom.center), 3),
|
107
|
+
round(a.min_dist, 1),
|
108
|
+
round(a.height, 1),
|
109
|
+
self.calc_mid_angle(a),
|
110
|
+
a)
|
109
111
|
|
110
|
-
|
112
|
+
def build_area_list(self, types=()):
|
113
|
+
arealist = self.geom.list_of_areas()
|
114
|
+
if types:
|
115
|
+
arealist = [a for a in arealist if a.type in types]
|
111
116
|
|
112
117
|
areas = []
|
113
118
|
for a in arealist:
|
114
|
-
areas.append((
|
115
|
-
round(a.min_dist, 1),
|
116
|
-
round(a.height, 1),
|
117
|
-
self.calc_mid_angle(a),
|
118
|
-
a))
|
119
|
+
areas.append(self.area_list_entry(a))
|
119
120
|
areas.sort(reverse=True)
|
121
|
+
return areas
|
120
122
|
|
123
|
+
def build_results(self, areas):
|
121
124
|
a0_alpha, a0_min_dist, a0_height, a0_mid_angle, a0 = areas[0]
|
122
125
|
equal_areas = [(a0_mid_angle, a0)]
|
123
126
|
check_rslt = []
|
124
127
|
for a1_alpha, a1_min_dist, a1_height, a1_mid_angle, a1 in areas[1:]:
|
125
|
-
if self.equal_area(a0_min_dist, a0_height, a0_alpha,
|
126
|
-
|
127
|
-
|
128
|
+
if (self.equal_area(a0_min_dist, a0_height, a0_alpha,
|
129
|
+
a1_min_dist, a1_height, a1_alpha,
|
130
|
+
rtol=0.001, atol=0.05)):
|
128
131
|
a0_min_dist = (a0_min_dist + a1_min_dist) / 2
|
129
132
|
a0_height = (a0_height + a1_height) / 2
|
130
133
|
a0_alpha = (a0_alpha + a1_alpha) / 2
|
131
134
|
equal_areas.append((a1_mid_angle, a1))
|
132
135
|
else:
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
136
|
+
# alpha Wechsel
|
137
|
+
id_list = []
|
138
|
+
for i in range(len(equal_areas)):
|
139
|
+
mid_angle0, area0 = equal_areas[i]
|
140
|
+
if area0.get_id() in id_list:
|
141
|
+
continue
|
142
|
+
equal_areas_check = [(mid_angle0, area0)]
|
143
|
+
for mid_angle1, area1 in equal_areas[i+1:]:
|
144
|
+
if area1.get_id() in id_list:
|
145
|
+
continue
|
146
|
+
if area0.is_symmetry_equal(area1):
|
147
|
+
equal_areas_check.append((mid_angle1, area1))
|
148
|
+
id_list.append(area1.get_id())
|
149
|
+
|
150
|
+
rslt = self.check_delta(equal_areas_check)
|
151
|
+
areasize = a0.area_size()
|
152
|
+
rslt['area'] = a0
|
153
|
+
rslt['areasize'] = areasize
|
154
|
+
check_rslt.append((areasize, rslt))
|
155
|
+
|
138
156
|
equal_areas = [(a1_mid_angle, a1)]
|
139
157
|
a0_min_dist = a1_min_dist
|
140
158
|
a0_height = a1_height
|
@@ -146,6 +164,89 @@ class Symmetry(object):
|
|
146
164
|
rslt['area'] = a0
|
147
165
|
rslt['areasize'] = areasize
|
148
166
|
check_rslt.append((areasize, rslt))
|
167
|
+
return check_rslt
|
168
|
+
|
169
|
+
def get_winding_symmetry(self, inside=False):
|
170
|
+
if inside:
|
171
|
+
areas = [self.area_list_entry(a) for a in self.geom.list_of_areas()
|
172
|
+
if not a.close_to_ag]
|
173
|
+
areas.sort(reverse=True)
|
174
|
+
else:
|
175
|
+
areas = self.build_area_list((AREA.TYPE_WINDINGS,))
|
176
|
+
|
177
|
+
logger.debug("begin of Symmetry::get_winding_symmetry: %s areas available", len(areas))
|
178
|
+
if not areas:
|
179
|
+
logger.debug("end of Symmetry::get_winding_symmetry: no areas")
|
180
|
+
return 0
|
181
|
+
|
182
|
+
check_rslt = self.build_results(areas)
|
183
|
+
logger.debug("%s results available", len(check_rslt))
|
184
|
+
[logger.debug("Result: %s", rslt) for rslt in check_rslt]
|
185
|
+
|
186
|
+
parts, start_delta = self.get_symmetry_parts(check_rslt)
|
187
|
+
if parts <= 1:
|
188
|
+
return 0
|
189
|
+
self.create_cut_lines(parts, start_delta)
|
190
|
+
|
191
|
+
sym = self.geom_part * parts
|
192
|
+
delta = 2*np.pi/sym
|
193
|
+
self.set_symmetry_parameters(self.startangle, parts, delta)
|
194
|
+
|
195
|
+
logger.debug("end of Symmetry::get_winding_symmetry: parts=%s", parts)
|
196
|
+
return parts
|
197
|
+
|
198
|
+
def get_magnet_symmetry(self):
|
199
|
+
areas = self.build_area_list((AREA.TYPE_MAGNET_AIRGAP, AREA.TYPE_MAGNET_RECT,))
|
200
|
+
air = self.build_area_list((AREA.TYPE_AIR,))
|
201
|
+
mag_list = [a for a in self.geom.list_of_areas() if a.is_magnet()]
|
202
|
+
air_list = [a for a in self.geom.list_of_areas() if a.is_air()]
|
203
|
+
sz_list = [a.area_size() for a in self.geom.list_of_areas()]
|
204
|
+
max_sz = max(sz_list)
|
205
|
+
for a in air_list:
|
206
|
+
if a.area_size() < max_sz * 0.005:
|
207
|
+
continue
|
208
|
+
for m in mag_list:
|
209
|
+
if a.is_touching(m):
|
210
|
+
areas.append(self.area_list_entry(a))
|
211
|
+
break
|
212
|
+
|
213
|
+
logger.debug("begin of Symmetry::get_magnet_symmetry: %s areas available", len(areas))
|
214
|
+
if not areas:
|
215
|
+
logger.debug("end of Symmetry::get_magnet_symmetry: no areas")
|
216
|
+
return 0
|
217
|
+
|
218
|
+
check_rslt = self.build_results(areas)
|
219
|
+
logger.debug("%s results available", len(check_rslt))
|
220
|
+
[logger.debug("Result: %s", rslt) for rslt in check_rslt]
|
221
|
+
for sz, rslt in check_rslt:
|
222
|
+
if not rslt.get('startdelta', 0.0) == 0.0:
|
223
|
+
return 0 # not proper
|
224
|
+
if rslt.get('halfslice', None):
|
225
|
+
return 0 # not proper
|
226
|
+
|
227
|
+
parts, start_delta = self.get_symmetry_parts(check_rslt)
|
228
|
+
if parts <= 1:
|
229
|
+
return 0
|
230
|
+
self.create_cut_lines(parts, start_delta)
|
231
|
+
|
232
|
+
sym = self.geom_part * parts
|
233
|
+
delta = 2*np.pi/sym
|
234
|
+
self.set_symmetry_parameters(self.startangle, parts, delta)
|
235
|
+
|
236
|
+
logger.debug("end of Symmetry::get_magnet_symmetry: parts=%s", parts)
|
237
|
+
return parts
|
238
|
+
|
239
|
+
def find_symmetry(self):
|
240
|
+
areas = self.build_area_list()
|
241
|
+
|
242
|
+
logger.debug("begin of Symmetry::find_symmetry: %s areas available", len(areas))
|
243
|
+
if not areas:
|
244
|
+
logger.debug("end of Symmetry::find_symmetry: no areas")
|
245
|
+
return 0
|
246
|
+
|
247
|
+
check_rslt = self.build_results(areas)
|
248
|
+
logger.debug("%s results available", len(check_rslt))
|
249
|
+
[logger.debug("Result: %s", rslt) for rslt in check_rslt]
|
149
250
|
|
150
251
|
parts, start_delta = self.get_symmetry_parts(check_rslt)
|
151
252
|
if parts < 2:
|
@@ -156,18 +257,7 @@ class Symmetry(object):
|
|
156
257
|
self.startangle = self.startangle - self.delta_angle_corr
|
157
258
|
self.endangle = self.endangle - self.delta_angle_corr
|
158
259
|
|
159
|
-
self.
|
160
|
-
for alpha in self.symmetry_lines(parts,
|
161
|
-
self.startangle,
|
162
|
-
start_delta,
|
163
|
-
self.endangle):
|
164
|
-
plus = self.geom.max_radius / 10
|
165
|
-
min_radius = max(10, self.geom.min_radius - plus)
|
166
|
-
p1 = point(self.geom.center, min_radius, alpha)
|
167
|
-
p2 = point(self.geom.center, self.geom.max_radius + plus, alpha)
|
168
|
-
line = Line(Element(start=p1, end=p2))
|
169
|
-
line.init_attributes(color='green')
|
170
|
-
self.geom.add_cut_line(line)
|
260
|
+
self.create_cut_lines(parts, start_delta)
|
171
261
|
|
172
262
|
logger.debug("end of Symmetry::find_symmetry: -> %s", parts)
|
173
263
|
return parts
|
@@ -177,6 +267,7 @@ class Symmetry(object):
|
|
177
267
|
result = {'areas': len(area_list),
|
178
268
|
'startdelta': 0.0,
|
179
269
|
'slices': None}
|
270
|
+
result['area_id_list'] = [a.get_id() for m, a in area_list]
|
180
271
|
if not area_list:
|
181
272
|
logger.debug("end of check_delta: no areas")
|
182
273
|
return result
|
@@ -375,9 +466,6 @@ class Symmetry(object):
|
|
375
466
|
|
376
467
|
dlist = []
|
377
468
|
x = 0
|
378
|
-
# logger.info("inx: %s", inx)
|
379
|
-
# [logger.info("%s deltas: %s", n, d) for n, d in deltas]
|
380
|
-
# [logger.info("area: %s", m) for m, a in area_list]
|
381
469
|
|
382
470
|
for i in inx:
|
383
471
|
for n in range(x, i):
|
@@ -833,6 +921,20 @@ class Symmetry(object):
|
|
833
921
|
logger.debug("return %s parts", parts)
|
834
922
|
return parts
|
835
923
|
|
924
|
+
def create_cut_lines(self, parts, start_delta):
|
925
|
+
self.geom.clear_cut_lines()
|
926
|
+
for alpha in self.symmetry_lines(parts,
|
927
|
+
self.startangle,
|
928
|
+
start_delta,
|
929
|
+
self.endangle):
|
930
|
+
plus = self.geom.max_radius / 10
|
931
|
+
min_radius = max(10, self.geom.min_radius - plus)
|
932
|
+
p1 = point(self.geom.center, min_radius, alpha)
|
933
|
+
p2 = point(self.geom.center, self.geom.max_radius + plus, alpha)
|
934
|
+
line = Line(Element(start=p1, end=p2))
|
935
|
+
line.init_attributes(color='green')
|
936
|
+
self.geom.add_cut_line(line)
|
937
|
+
|
836
938
|
def symmetry_lines(self, parts, startangle, start_delta, endangle):
|
837
939
|
logger.debug("begin symmetry_lines from %s to %s with start %s",
|
838
940
|
startangle,
|
@@ -858,14 +960,17 @@ class Symmetry(object):
|
|
858
960
|
yield start
|
859
961
|
|
860
962
|
# Damit man anschliessend ohne Umstände schneiden kann.
|
861
|
-
self.
|
862
|
-
|
963
|
+
self.set_symmetry_parameters(sym_startangle, parts, delta)
|
964
|
+
logger.debug("end symmetry_lines")
|
965
|
+
|
966
|
+
def set_symmetry_parameters(self, startangle, parts, delta):
|
967
|
+
self.geom.sym_startangle = startangle
|
968
|
+
self.geom.sym_endangle = startangle + delta
|
863
969
|
self.geom.sym_slices = parts
|
864
970
|
self.geom.sym_slice_angle = delta
|
865
971
|
self.geom.sym_area = Area([], (0,0), 0.0)
|
866
972
|
self.geom.sym_area.sym_startangle = self.geom.sym_startangle
|
867
973
|
self.geom.sym_area.sym_endangle = self.geom.sym_endangle
|
868
|
-
logger.debug("end symmetry_lines")
|
869
974
|
|
870
975
|
def check_symmetry_of_mirror(self, mirror_geom, mirrorangle):
|
871
976
|
logger.debug("begin of Symmetry::check_symmetry_of_mirror")
|