femagtools 1.8.1__py3-none-any.whl → 1.8.3__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/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")
|