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.
Files changed (49) hide show
  1. femagtools/__init__.py +1 -1
  2. femagtools/dxfsl/area.py +110 -1
  3. femagtools/dxfsl/areabuilder.py +93 -45
  4. femagtools/dxfsl/conv.py +5 -0
  5. femagtools/dxfsl/converter.py +85 -27
  6. femagtools/dxfsl/fslrenderer.py +5 -4
  7. femagtools/dxfsl/functions.py +14 -6
  8. femagtools/dxfsl/geom.py +135 -149
  9. femagtools/dxfsl/journal.py +1 -1
  10. femagtools/dxfsl/machine.py +161 -9
  11. femagtools/dxfsl/shape.py +46 -1
  12. femagtools/dxfsl/svgparser.py +1 -1
  13. femagtools/dxfsl/symmetry.py +143 -38
  14. femagtools/femag.py +64 -61
  15. femagtools/fsl.py +15 -12
  16. femagtools/isa7.py +3 -2
  17. femagtools/machine/__init__.py +5 -4
  18. femagtools/machine/afpm.py +79 -33
  19. femagtools/machine/effloss.py +29 -18
  20. femagtools/machine/sizing.py +192 -13
  21. femagtools/machine/sm.py +34 -36
  22. femagtools/machine/utils.py +2 -2
  23. femagtools/mcv.py +58 -29
  24. femagtools/model.py +4 -3
  25. femagtools/multiproc.py +79 -80
  26. femagtools/parstudy.py +11 -5
  27. femagtools/plot/nc.py +2 -2
  28. femagtools/semi_fea.py +108 -0
  29. femagtools/templates/basic_modpar.mako +0 -3
  30. femagtools/templates/fe-contr.mako +18 -18
  31. femagtools/templates/ld_lq_fast.mako +3 -0
  32. femagtools/templates/mult_cal_fast.mako +3 -0
  33. femagtools/templates/pm_sym_f_cur.mako +4 -1
  34. femagtools/templates/pm_sym_fast.mako +3 -0
  35. femagtools/templates/pm_sym_loss.mako +3 -0
  36. femagtools/templates/psd_psq_fast.mako +3 -0
  37. femagtools/templates/torq_calc.mako +3 -0
  38. femagtools/tks.py +23 -20
  39. femagtools/zmq.py +213 -0
  40. {femagtools-1.8.1.dist-info → femagtools-1.8.3.dist-info}/METADATA +3 -3
  41. {femagtools-1.8.1.dist-info → femagtools-1.8.3.dist-info}/RECORD +49 -47
  42. {femagtools-1.8.1.dist-info → femagtools-1.8.3.dist-info}/WHEEL +1 -1
  43. tests/test_afpm.py +15 -6
  44. tests/test_femag.py +1 -1
  45. tests/test_fsl.py +4 -4
  46. tests/test_mcv.py +21 -15
  47. {femagtools-1.8.1.dist-info → femagtools-1.8.3.dist-info}/LICENSE +0 -0
  48. {femagtools-1.8.1.dist-info → femagtools-1.8.3.dist-info}/entry_points.txt +0 -0
  49. {femagtools-1.8.1.dist-info → femagtools-1.8.3.dist-info}/top_level.txt +0 -0
@@ -247,16 +247,21 @@ class Machine(object):
247
247
  startangle=self.startangle,
248
248
  endangle=self.endangle)
249
249
 
250
- def full_copy(self, concatenate_matching_el=False):
250
+ def clone(self):
251
251
  clone = self.geom.copy_shape(self.radius,
252
252
  0.0, 2*np.pi,
253
- 0.0, self.radius+9999,
254
- concatenate_matching_el=concatenate_matching_el)
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
- self.geom = clone
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-4
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
- from .area import TYPE_WINDINGS
594
- return self.geom.area_size_of_type(TYPE_WINDINGS)
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.set_edge_attributes()
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:
@@ -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.info("subregion %d: %s", sr, m.groups()[0])
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"):
@@ -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 find_symmetry(self):
104
- arealist = self.geom.list_of_areas()
105
- logger.debug("begin of Symmetry::find_symmetry: %s areas available", len(arealist))
106
- if len(arealist) == 0:
107
- logger.debug("end of find_symmetry: no areas")
108
- return 0
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
- logger.debug("startangle=%s, endangle=%s", self.startangle, self.endangle)
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((round(a.get_alpha(self.geom.center), 3),
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
- a1_min_dist, a1_height, a1_alpha,
127
- rtol=0.001, atol=0.05):
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
- rslt = self.check_delta(equal_areas)
134
- areasize = a0.area_size()
135
- rslt['area'] = a0
136
- rslt['areasize'] = areasize
137
- check_rslt.append((areasize, rslt))
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.geom.clear_cut_lines()
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.geom.sym_startangle = sym_startangle
862
- self.geom.sym_endangle = sym_startangle + delta
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")