femagtools 1.8.3__py3-none-any.whl → 1.8.5__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/dxfsl/geom.py CHANGED
@@ -2256,45 +2256,120 @@ class Geometry(object):
2256
2256
  return center[0]
2257
2257
  return None
2258
2258
 
2259
- def get_center_arcs(self):
2259
+ def is_same_center(self, center_lst, center, rtol, atol):
2260
+ for c in center_lst:
2261
+ if points_are_close(c['center'], center['center'], rtol, atol):
2262
+ radius = center['radius'][0]
2263
+ if not radius in c['radius']:
2264
+ c['radius'].append(radius)
2265
+ c['count'] = c['count'] + 1
2266
+ return True
2267
+ return False
2268
+
2269
+ def get_center_with_x(self, center_lst, x):
2270
+ c_list = [c for c in center_lst
2271
+ if np.isclose(c['center'][0], x, rtol=self.rtol, atol=self.atol)]
2272
+ if not c_list:
2273
+ return None
2274
+ cy_list = [(c['center'][1], c) for c in c_list]
2275
+ cy_list.sort()
2276
+ y, c = cy_list[0]
2277
+ return c
2278
+
2279
+ def get_center_with_y(self, center_lst, y):
2280
+ c_list = [c for c in center_lst
2281
+ if np.isclose(c['center'][1], y, rtol=self.rtol, atol=self.atol)]
2282
+ if not c_list:
2283
+ return None
2284
+ cy_list = [(c['center'][0], c) for c in c_list]
2285
+ cy_list.sort()
2286
+ [logger.info("y=%s, c=%s", y, c) for y, c in cy_list]
2287
+ y, c = cy_list[0]
2288
+ return c
2289
+
2290
+ def get_center_arcs(self, mm):
2260
2291
  logger.debug("begin of get_center_arcs")
2261
2292
  center_list = []
2293
+ x_min, x_max, y_min, y_max = mm
2294
+
2295
+ def center_is_inside(c):
2296
+ tol = 0.1
2297
+ x, y = c
2298
+ if x-tol > x_min and \
2299
+ x+tol < x_max and \
2300
+ y-tol > y_min and \
2301
+ y+tol < y_max:
2302
+ return True
2303
+ return False
2304
+
2262
2305
  circles = [e for e in self.elements() if is_Circle(e)]
2263
2306
  logger.debug(" -- %s Circles", len(circles))
2264
2307
 
2265
2308
  for e in circles:
2266
2309
  center = (round(e.center[0], 3), round(e.center[1], 3))
2267
- radius = round(e.radius, 1)
2268
- center_list.append(([1], center, [radius]))
2310
+ entry = {'center': center,
2311
+ 'radius': [round(e.radius, 1)],
2312
+ 'phi': e.get_angle_of_arc(),
2313
+ 'dist': e.length(),
2314
+ 'inside': center_is_inside(center),
2315
+ 'count': 1}
2316
+ center_list.append(entry)
2269
2317
 
2270
2318
  arcs = [e for e in self.elements() if is_Arc(e)]
2271
2319
  logger.debug(" -- %s Arcs", len(arcs))
2272
2320
 
2273
2321
  for e in arcs:
2274
2322
  center = (round(e.center[0], 3), round(e.center[1], 3))
2275
- radius = round(e.radius, 1)
2276
- c = self.get_same_center(center_list, center, self.rtol, self.atol)
2277
- if c is None:
2278
- center_list.append(([1], center, [radius]))
2279
- else:
2280
- c[0][0] += 1
2281
- if radius not in c[2]:
2282
- c[2].append(radius)
2323
+ entry = {'center': center,
2324
+ 'radius': [round(e.radius, 1)],
2325
+ 'phi': e.get_angle_of_arc(),
2326
+ 'dist': e.length(),
2327
+ 'inside': center_is_inside(center),
2328
+ 'count': 1}
2329
+ if not self.is_same_center(center_list, entry, self.rtol, self.atol):
2330
+ center_list.append(entry)
2283
2331
 
2284
2332
  center = None
2285
- arc_list = [[len(c[2]), c[0][0], c[1]] for c in center_list]
2333
+ arc_list = [[c['count'], len(c['radius']), c['phi'], n, c]
2334
+ for n, c in enumerate(center_list)]
2286
2335
  arc_list.sort(reverse=True)
2287
2336
 
2288
- if arc_list:
2289
- c1 = arc_list[0]
2290
- center = c1[2]
2291
- if len(arc_list) > 1:
2292
- c2 = arc_list[1]
2293
- if not c1[0] > c2[0]:
2294
- center = None
2337
+ logger.debug("x min/max = %s/%s", x_min, x_max)
2338
+ logger.debug("y min/max = %s/%s", y_min, y_max)
2295
2339
 
2296
- logger.debug("end of get_center_arcs: -> %s", center)
2297
- return center
2340
+ [logger.debug("Arc %s", arc) for arc in arc_list]
2341
+ if not arc_list:
2342
+ logger.debug("end of get_center_arcs: no arcs")
2343
+ return None
2344
+
2345
+ cnt, cr1, p, n, c1 = arc_list[0]
2346
+ logger.debug("First Entry: %s", c1)
2347
+ center = c1['center']
2348
+ if len(arc_list) > 1:
2349
+ cnt, cr2, p, n, c2 = arc_list[1]
2350
+ logger.debug("Second Entry: %s", c2)
2351
+ if not cr1 > cr2:
2352
+ center = None
2353
+
2354
+ if center:
2355
+ logger.debug("end of get_center_arcs: -> %s", center)
2356
+ return center
2357
+
2358
+ c_entry = self.get_center_with_x(center_list, x_min)
2359
+ if c_entry:
2360
+ center = c_entry['center']
2361
+ if center[1] < y_min:
2362
+ logger.debug("end of get_center_arcs: x -> %s", center)
2363
+ return center
2364
+ c_entry = self.get_center_with_y(center_list, y_min)
2365
+ if c_entry:
2366
+ center = c_entry['center']
2367
+ if center[0] < x_min:
2368
+ logger.debug("end of get_center_arcs: y -> %s", center)
2369
+ return center
2370
+
2371
+ logger.debug("end of get_center_arcs: no center found")
2372
+ return None
2298
2373
 
2299
2374
  def get_center_dim(self, mm):
2300
2375
  return (round(mm[0], 4), round(mm[2], 4))
@@ -2305,7 +2380,9 @@ class Geometry(object):
2305
2380
  return None
2306
2381
 
2307
2382
  center = None
2308
- center_arcs = self.get_center_arcs()
2383
+ # Zuerst suchen wir anhand der Circle- und Arc-Segmente nach einem
2384
+ # möglichen Center-Punkt.
2385
+ center_arcs = self.get_center_arcs(mm)
2309
2386
 
2310
2387
  if center_arcs:
2311
2388
  center = center_arcs
@@ -3259,7 +3336,7 @@ class Geometry(object):
3259
3336
  max_size, max_w = windings_surface[0]
3260
3337
  for sz, w in windings_surface[1:]:
3261
3338
  logger.debug("winding size = %s", sz)
3262
- if sz / max_size < 0.80:
3339
+ if sz / max_size < 0.70:
3263
3340
  w.set_type(AREA.TYPE_AIR)
3264
3341
  if sz / max_size < 0.2:
3265
3342
  windings_found -= 1
@@ -135,6 +135,16 @@ class Machine(object):
135
135
  self.geom.is_outer = True
136
136
  self.geom.is_inner = False
137
137
 
138
+ def set_attributes(self,
139
+ kind="",
140
+ inner=False,
141
+ outer=False):
142
+ self.set_kind(kind)
143
+ if inner:
144
+ self.set_inner()
145
+ if outer:
146
+ self.set_outer()
147
+
138
148
  def clear_cut_lines(self):
139
149
  self.geom.clear_cut_lines()
140
150
  if self.mirror_geom is not None:
@@ -635,9 +645,13 @@ class Machine(object):
635
645
  parts = symmetry.find_symmetry() # temp solution
636
646
  logger.debug(">>> Symmetry parts = %s <<<", parts)
637
647
 
638
- if parts > 1:
639
- found = True
640
- else:
648
+ if parts == 1:
649
+ # no slices, but ok
650
+ return False
651
+
652
+ found = (parts > 1)
653
+
654
+ if not found:
641
655
  found = self.geom.find_symmetry(self.radius,
642
656
  self.startangle,
643
657
  self.endangle,
@@ -833,11 +847,11 @@ class Machine(object):
833
847
  if dist_start > dist_end:
834
848
  machine.mirror_all_areas(self.startangle)
835
849
  machine.rotate_to(angle)
836
- machine.geom.create_list_of_areas(delete=True)
837
850
  machine.startangle -= angle
838
851
  else:
839
852
  machine.mirror_all_areas(self.endangle)
840
853
  machine.endangle += angle
854
+ machine.geom.create_list_of_areas(delete=True)
841
855
  machine.set_alfa_and_corners()
842
856
  machine.part = machine.part_of_circle()
843
857
  machine.geom.set_subregion_parameters(self.startangle,
@@ -907,23 +921,25 @@ class Machine(object):
907
921
  first_thirdangle,
908
922
  second_thirdangle)
909
923
  machine_mirror_1.clear_cut_lines()
910
-
911
924
  machine_mirror_1.repair_hull()
912
925
  machine_mirror_1.set_alfa_and_corners()
926
+ if machine_mirror_1.geom.number_of_edges() < 2: # very bad
927
+ logger.debug("end get_third_symmetry_mirror: no remaining elements")
928
+ return None
913
929
  if not machine_mirror_1.check_symmetry_graph(0.001, 0.05):
914
930
  logger.debug("end get_third_symmetry_mirror: no mirror first third")
915
931
  return None
916
932
 
917
933
  if plt:
918
934
  plt.render_elements(machine_mirror_1.geom, Shape,
919
- title="Part",
935
+ title="Part 1",
920
936
  show=True,
921
937
  with_corners=False,
922
938
  with_nodes=False,
923
939
  neighbors=True)
924
940
 
925
941
  plt.render_elements(machine_mirror_1.mirror_geom, Shape,
926
- title="Counterpart",
942
+ title="Counterpart 1",
927
943
  show=True,
928
944
  with_corners=False,
929
945
  with_nodes=False,
@@ -935,10 +951,28 @@ class Machine(object):
935
951
  machine_mirror_2.clear_cut_lines()
936
952
  machine_mirror_2.repair_hull()
937
953
  machine_mirror_2.set_alfa_and_corners()
954
+ if machine_mirror_2.geom.number_of_edges() < 2: # very bad
955
+ logger.debug("end get_third_symmetry_mirror: no remaining elements")
956
+ return None
938
957
  if not machine_mirror_2.check_symmetry_graph(0.001, 0.05):
939
958
  logger.debug("end get_third_symmetry_mirror: no mirror second third")
940
959
  return None
941
960
 
961
+ if plt:
962
+ plt.render_elements(machine_mirror_2.geom, Shape,
963
+ title="Part 2",
964
+ show=True,
965
+ with_corners=False,
966
+ with_nodes=False,
967
+ neighbors=True)
968
+
969
+ plt.render_elements(machine_mirror_2.mirror_geom, Shape,
970
+ title="Counterpart 2",
971
+ show=True,
972
+ with_corners=False,
973
+ with_nodes=False,
974
+ neighbors=True)
975
+
942
976
  machine_mirror_1.previous_machine = self
943
977
  logger.debug("end get_third_symmetry_mirror: ok")
944
978
  return machine_mirror_1
@@ -992,6 +1026,9 @@ class Machine(object):
992
1026
  with_nodes=False,
993
1027
  neighbors=True)
994
1028
 
1029
+ if machine_mirror.geom.number_of_edges() < 2: # very bad
1030
+ logger.debug("end get_symmetry_mirror: no remaining elements")
1031
+ return None
995
1032
  if machine_mirror.check_symmetry_graph(0.001, 0.05):
996
1033
  machine_mirror.previous_machine = self
997
1034
  machine_mirror.rotate_to(0.0)
femagtools/dxfsl/shape.py CHANGED
@@ -467,6 +467,10 @@ class Circle(Shape):
467
467
  r0 = np.linalg.norm(self.center)
468
468
  return max(abs(r-r0-self.radius), abs(r-r0+self.radius))
469
469
 
470
+ def length(self):
471
+ """returns length of this circle"""
472
+ return self.radius*2*np.pi
473
+
470
474
  def overlapping_shape(self, e, rtol=1e-03, atol=1e-03):
471
475
  if not (isinstance(e, Arc) or isinstance(e, Circle)):
472
476
  # end overlapping_shape: Circle (not Arc or Circle)
@@ -120,7 +120,15 @@ class Symmetry(object):
120
120
  areas.sort(reverse=True)
121
121
  return areas
122
122
 
123
+ def get_equal_areas(self, areas):
124
+ return
125
+
123
126
  def build_results(self, areas):
127
+ logger.debug("begin of build_results with %s areas", len(areas))
128
+ [logger.debug("#%s: alpha=%s, min=%s, max=%s",
129
+ a.get_id(), alpha, a.min_angle, a.max_angle) for
130
+ alpha, dist, h, mid, a in areas]
131
+
124
132
  a0_alpha, a0_min_dist, a0_height, a0_mid_angle, a0 = areas[0]
125
133
  equal_areas = [(a0_mid_angle, a0)]
126
134
  check_rslt = []
@@ -164,6 +172,7 @@ class Symmetry(object):
164
172
  rslt['area'] = a0
165
173
  rslt['areasize'] = areasize
166
174
  check_rslt.append((areasize, rslt))
175
+ logger.debug("end of build_results")
167
176
  return check_rslt
168
177
 
169
178
  def get_winding_symmetry(self, inside=False):
@@ -246,7 +255,6 @@ class Symmetry(object):
246
255
 
247
256
  check_rslt = self.build_results(areas)
248
257
  logger.debug("%s results available", len(check_rslt))
249
- [logger.debug("Result: %s", rslt) for rslt in check_rslt]
250
258
 
251
259
  parts, start_delta = self.get_symmetry_parts(check_rslt)
252
260
  if parts < 2:
@@ -665,6 +673,9 @@ class Symmetry(object):
665
673
  m1 = m2
666
674
  d1 = d2
667
675
 
676
+ if not mid_list:
677
+ return None
678
+
668
679
  logger.debug("New Mids: %s", mid_list)
669
680
  delta = positive_angle(mid_list[0] * 2)
670
681
  delta_list = [delta]
@@ -712,6 +723,41 @@ class Symmetry(object):
712
723
  logger.debug("end check_first_last_difference => %s", n1 + 1)
713
724
  return n1 + 1
714
725
 
726
+ def concatenate_results(self, check_rslt):
727
+ if len(check_rslt) < 2:
728
+ return check_rslt
729
+ # ----------
730
+ def get_slices(rslt):
731
+ if rslt['slices'] is None:
732
+ return 0
733
+ if rslt.get('startdelta', 0.0) != 0.0:
734
+ return 0
735
+ if rslt.get('halfslice', None) is not None:
736
+ return 0
737
+ return rslt['slices']
738
+ # ------
739
+ new_rslt = []
740
+ size1, n1, rslt1 = check_rslt[0]
741
+ slices1 = get_slices(rslt1)
742
+ for size2, n2, rslt2 in check_rslt[1:]:
743
+ slices2 = get_slices(rslt2)
744
+ if slices1 > 0 and \
745
+ slices1 == slices2 and \
746
+ np.isclose(size1, size2, rtol=1e-01, atol=1e-01) and \
747
+ (rslt1.get('delta_corr', 0.0) == 0.0 or \
748
+ rslt2.get('delta_corr', 0.0) == 0.0):
749
+ # concatenate
750
+ rslt1['slices'] = None
751
+ rslt2['delta_corr'] = 0.0
752
+ rslt2['areas'] = rslt2['areas'] + rslt1['areas']
753
+ logger.debug("concatenate results(size %s)", size1)
754
+ else:
755
+ new_rslt.append((size1, n1, rslt1))
756
+ slices1, size1, n1, rslt1 = (slices2, size2, n2, rslt2)
757
+
758
+ new_rslt.append((size1, n1, rslt1))
759
+ return new_rslt
760
+
715
761
  def get_symmetry_parts(self, check_rslt):
716
762
  max_size = 0
717
763
  max_areas = 0
@@ -720,10 +766,11 @@ class Symmetry(object):
720
766
  self.delta_angle_corr = None
721
767
  unsure_sym = False
722
768
 
723
- check_rslt = [(size, n, rslt) for n, (size, rslt) in enumerate(check_rslt)]
769
+ check_rslt = [(size, n, rslt) for n, (size, rslt) in enumerate(check_rslt)
770
+ if rslt['slices'] is not None]
724
771
  check_rslt.sort(reverse=True)
725
- for size, n, rslt in check_rslt:
726
- logger.debug("Result: %s, %s", size, rslt)
772
+ check_rslt = self.concatenate_results(check_rslt)
773
+ [logger.debug("Result #%s: %s, %s", n, size, rslt) for size, n, rslt in check_rslt]
727
774
 
728
775
  rtol = 1e-3
729
776
  atol = 1e-2
@@ -740,40 +787,46 @@ class Symmetry(object):
740
787
  for size, n, rslt in check_rslt:
741
788
  areas = rslt['areas']
742
789
  slices = rslt['slices']
790
+ if slices is None:
791
+ continue
792
+
743
793
  size = rslt['areasize']
744
794
  angle_corr = rslt.get('delta_corr', 0.0)
745
795
 
746
796
  if rslt.get('halfslice', 0) == 1:
747
797
  halfslice.append(rslt)
748
798
 
749
- if slices is not None:
750
- if slices > 0:
751
- max_size = max(max_size, size)
752
- max_areas = max(max_areas, areas)
753
- max_slices = max(max_slices, slices)
754
- missing_middles += rslt.get('missing_middles', [])
755
- area = rslt['area']
756
- if not (np.isclose(area.min_dist,
757
- self.geom.min_radius,
758
- rtol=1e-4, atol=1e-3) and \
759
- np.isclose(area.max_dist,
760
- self.geom.max_radius,
761
- rtol=1e-4, atol=1e-3)):
762
- if rslt.get('delta_corr', 0.0) == 0.0:
763
- without_angle_corr += areas * size
764
- else:
765
- with_angle_corr += areas * size
799
+ if slices > 0:
800
+ max_size = max(max_size, size)
801
+ max_areas = max(max_areas, areas)
802
+ max_slices = max(max_slices, slices)
803
+ missing_middles += rslt.get('missing_middles', [])
804
+ area = rslt['area']
805
+ if not (np.isclose(area.min_dist,
806
+ self.geom.min_radius,
807
+ rtol=1e-4, atol=1e-3) and \
808
+ np.isclose(area.max_dist,
809
+ self.geom.max_radius,
810
+ rtol=1e-4, atol=1e-3)):
811
+ if rslt.get('delta_corr', 0.0) == 0.0:
812
+ without_angle_corr += areas * size
766
813
  else:
767
- maybe_angle_korr += areas * size
814
+ with_angle_corr += areas * size
815
+ else:
816
+ maybe_angle_korr += areas * size
817
+
768
818
  logger.debug("max size: %s, max areas: %s", max_size, max_areas)
819
+ logger.debug("Angle-Corrections: %s Yes, %s No, %s Maybe",
820
+ with_angle_corr,
821
+ without_angle_corr,
822
+ maybe_angle_korr)
769
823
 
770
- logger.debug("Angle-Corrections: %s Yes, %s No",
771
- with_angle_corr, without_angle_corr)
772
824
  if np.isclose(with_angle_corr, without_angle_corr):
773
825
  with_angle_corr = (maybe_angle_korr > 0)
774
826
  else:
775
827
  with_angle_corr = (with_angle_corr > without_angle_corr)
776
828
 
829
+ # -------------------------
777
830
  def get_halfslice_counterpart(rslt):
778
831
  if rslt.get('halfslice', 0) != 2:
779
832
  return None
@@ -788,7 +841,7 @@ class Symmetry(object):
788
841
  np.isclose(alpha1, alpha2, rtol=rtol, atol=atol):
789
842
  return half
790
843
  return None
791
-
844
+ # -----------
792
845
  if halfslice:
793
846
  logger.debug("%s halfslice [1] found", len(halfslice))
794
847
 
femagtools/fsl.py CHANGED
@@ -556,7 +556,6 @@ class Builder:
556
556
  if 'fsl_rotor' in conv:
557
557
  self.fsl_rotor = True
558
558
  th_props = ['']
559
- logger.debug(model['magnet'])
560
559
  if hasattr(model, 'magnet'):
561
560
  if model['magnet'].get('thcond', 0):
562
561
  th_props = [f'rotor_density = {model["magnet"]["density"]}',