femagtools 1.8.3__py3-none-any.whl → 1.8.5__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
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"]}',