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.
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")