femagtools 1.8.3__py3-none-any.whl → 1.8.4__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"]}',
@@ -11,7 +11,7 @@ from .. import model
11
11
  from .. import utils
12
12
  from .. import windings
13
13
  from .. import femag
14
- from scipy.interpolate import RegularGridInterpolator, interp1d, RectBivariateSpline
14
+ from scipy.interpolate import make_interp_spline, RegularGridInterpolator, RectBivariateSpline
15
15
  from scipy.integrate import quad
16
16
  import copy
17
17
 
@@ -58,7 +58,7 @@ def _integrate(radius, pos, val):
58
58
 
59
59
 
60
60
  def _integrate1d(radius, val):
61
- interp = interp1d(radius, val)
61
+ interp = make_interp_spline(radius, val, k=1)
62
62
  def func(x):
63
63
  return interp((x))
64
64
  return quad(func, radius[0], radius[-1])[0]
@@ -166,9 +166,9 @@ def _generate_mesh(n, T, nb, Tb, npoints):
166
166
  nmax = max(n)
167
167
  tmin, tmax = 0, max(T)
168
168
  tnum = npoints[1]
169
- tip = ip.interp1d(n, T)
169
+ tip = ip.make_interp_spline(n, T, k=1)
170
170
  if nb and Tb:
171
- tbip = ip.interp1d(nb, Tb)
171
+ tbip = ip.make_interp_spline(nb, Tb, k=1)
172
172
  else:
173
173
  def tbip(x): return 0
174
174
 
femagtools/machine/im.py CHANGED
@@ -35,6 +35,9 @@ def log_interp1d(x, y, kind='cubic'):
35
35
  logy = np.log10(yy)
36
36
  lin_interp = ip.interp1d(logx, logy, kind=kind, fill_value="extrapolate")
37
37
  def log_interp(zz): return np.power(10.0, lin_interp(np.log10(zz)))
38
+ # TODO check replace interp1d
39
+ #lin_interp = ip.make_interp_spline(logx, logy, bc_type='not-a-knot')
40
+ #def log_interp(zz): return np.power(10.0, lin_interp(np.log10(zz), nu=1))
38
41
  return log_interp
39
42
 
40
43
 
@@ -792,15 +795,10 @@ def parident(workdir, engine, f1, u1, wdgcon,
792
795
  tend = time.time()
793
796
  logger.info("Elapsed time %d s Status %s",
794
797
  (tend-tstart), status)
798
+ if any([x != 'C' for x in status]):
799
+ raise ValueError("AC simulation failed")
795
800
  # collect results
796
- results = []
797
- errors = []
798
- for t in job.tasks:
799
- if t.status == 'C':
800
- results.append(t.get_results())
801
- else:
802
- logger.warning("Status %s", t.status)
803
- results.append({})
801
+ results = [t.get_results() for t in job.tasks]
804
802
 
805
803
  i1_0 = results[0]['i1_0'].tolist()
806
804
  psi1_0 = results[0]['psi1_0'].tolist()
femagtools/machine/sm.py CHANGED
@@ -187,7 +187,7 @@ def parident(workdir, engine, machine,
187
187
 
188
188
  if simulation['calculationMode'] == 'ld_lq_fast':
189
189
  dqpars = dict(m=3, p=b['machine']['p'],
190
- r1=r1,
190
+ r1=float(r1),
191
191
  r2=machine['rotor'].get('resistance', 1),
192
192
  rotor_mass=rotor_mass, kfric_b=1,
193
193
  ldq=[dict(
@@ -434,7 +434,7 @@ class SynchronousMachine(object):
434
434
  def iqd_tmech(self, torque, n, disp=False, maxiter=500):
435
435
  """return currents for shaft torque with minimal losses"""
436
436
  if torque > 0:
437
- startvals = self.bounds[0][1], 0, self.bounds[-1][1]
437
+ startvals = self.bounds[0][1]/2, 0, self.bounds[-1][1]
438
438
  else:
439
439
  startvals = -self.bounds[0][1]/2, 0, self.bounds[-1][1]
440
440
 
femagtools/mcv.py CHANGED
@@ -12,7 +12,7 @@ import pathlib
12
12
  import struct
13
13
  import math
14
14
  import numpy as np
15
- import scipy.interpolate as ip
15
+ from scipy.interpolate import make_interp_spline
16
16
  from six import string_types
17
17
  import femagtools.losscoeffs as lc
18
18
 
@@ -99,7 +99,7 @@ def norm_pfe(B, pfe):
99
99
  b = list(b)
100
100
  b[-1] = Bv[n]
101
101
  n += 1
102
- pfunc = ip.interp1d(b, pfe[i], kind='cubic')
102
+ pfunc = make_interp_spline(b, pfe[i])
103
103
  m.append([float(pfunc(x))
104
104
  for x in Bv[:n]] + [None]*(len(Bv)-n))
105
105
  return Bv.tolist(), m
@@ -168,8 +168,7 @@ def recalc_bsin(curve):
168
168
  if bi[0] > 0:
169
169
  bi.insert(0, 0)
170
170
  hi.insert(0, 0)
171
- bh = ip.interp1d(bi, hi,
172
- kind='cubic', assume_sorted=True)
171
+ bh = make_interp_spline(bi, hi)
173
172
  for bx in c['bi'][2:]:
174
173
  bt = bx*np.sin(2*np.pi/4/ndel*x)
175
174
  nue = np.sum(bh(bt)/bt)/ndel
@@ -196,8 +195,7 @@ def recalc_hsin(curve):
196
195
  if hi[0] > 0:
197
196
  hi.insert(0, 0)
198
197
  bi.insert(0, 0)
199
- hb = ip.interp1d(hi, bi,
200
- kind='cubic', assume_sorted=True)
198
+ hb = make_interp_spline(hi, bi)
201
199
  for hx in c['hi'][2:]:
202
200
  ht = hx*np.sin(2*np.pi/4/ndel*x)
203
201
  bt = hb(ht)*np.sin(2*np.pi/4/ndel*x)
@@ -243,11 +241,12 @@ def approx(db2, curve, ctype):
243
241
  if ctype in (DEMCRV, MAG_AC_CRV):
244
242
  dhdbn = 0
245
243
  k = len(bi2)-1
246
- if curve['bi'][k] - curve['bi'][k-1] > 0:
247
- dhdbn = ((curve['hi'][k] - curve['h'][k-1],KK)
248
- /(curve['bi'][k] - curve['bi'][k-1]))
249
- a.append(MUE0*dhdbn)
250
- b.append(MUE0*curve['hi'][k] - dhdbn*curve['bi'][k])
244
+ if k < len(curve['bi']):
245
+ if curve['bi'][k] - curve['bi'][k-1] > 0:
246
+ dhdbn = ((curve['hi'][k] - curve['h'][k-1])
247
+ /(curve['bi'][k] - curve['bi'][k-1]))
248
+ a.append(MUE0*dhdbn)
249
+ b.append(MUE0*curve['hi'][k] - dhdbn*curve['bi'][k])
251
250
  else:
252
251
  a.append(1.0)
253
252
  b.append(MUE0*curve['hi'][-1]-curve['bi'][-1])
@@ -44,10 +44,16 @@ if not airgap_created then
44
44
  nc_line(r2, 0.0, x2, y2, 0.0)
45
45
 
46
46
  if m.tot_num_slot > m.num_sl_gen then
47
+ if inner_da_end == nil then
48
+ inner_da_end = inner_da_start
49
+ end
47
50
  x3, y3 = pr2c(inner_da_end, alfa)
48
51
  x4, y4 = pr2c(r1, alfa)
49
52
  nc_line(x3, y3, x4, y4, 0, 0)
50
53
 
54
+ if outer_da_end == nil then
55
+ outer_da_end = outer_da_start
56
+ end
51
57
  x3, y3 = pr2c(outer_da_end, alfa)
52
58
  x4, y4 = pr2c(r2, alfa)
53
59
  nc_line(x3, y3, x4, y4, 0, 0)
femagtools/utils.py CHANGED
@@ -17,7 +17,7 @@ def fft(pos, y, pmod=0):
17
17
  else:
18
18
  #negative_periodic = np.abs(y[0] - y[-1])/np.max(y) > 1
19
19
  # count zero crossings
20
- ypos = np.asarray(y[:-1]) > 0
20
+ ypos = np.asarray(y[:-1])-np.mean(y[:-1]) > 0
21
21
  nypos = ~ypos
22
22
  nzc = len(((ypos[:-1] & nypos[1:])
23
23
  | (nypos[:-1] & ypos[1:])).nonzero()[0])
femagtools/windings.py CHANGED
@@ -179,10 +179,10 @@ class Winding(object):
179
179
  nue = n
180
180
  else:
181
181
  nue = self.kw_order(n)
182
- #if q1 == q2: # integral slot winding
183
- # q = self.Q/2/self.m/self.p
184
- # nuep = nue/self.p
185
- # return np.sin(nuep*np.pi/2/self.m)/q/np.sin(nuep*np.pi/2/self.m/q)
182
+ if q1 == q2: # integral slot winding
183
+ q = self.Q/2/self.m/self.p
184
+ nuep = nue/self.p
185
+ return np.sin(nuep*np.pi/2/self.m)/q/np.sin(nuep*np.pi/2/self.m/q)
186
186
  k = 2 if self.l == 1 else 1
187
187
  a = nue*k*np.pi/self.Q*Yk
188
188
  t = self.Q//Qb
@@ -416,6 +416,13 @@ class Winding(object):
416
416
  [[d*s for s, d in zip(l, ld)] for l, ld in zip(lower, ldirs)])
417
417
  # complete if not basic winding:
418
418
  Qb = self.Q//num_basic_windings(self.Q, self.p, self.l)
419
+
420
+ if not np.asarray(upper).size or not np.asarray(lower).size:
421
+ layers = 1
422
+ if layers == 1 and z[1]:
423
+ z = ([[d*s for s, d in zip(l, ld)] for l, ld in zip(lower, ldirs)],
424
+ [[d*s for s, d in zip(u, ud)] for u, ud in zip(upper, udirs)])
425
+
419
426
  if max([abs(n) for m in z[0] for n in m]) < Qb:
420
427
  return [[k + [-n+Qb//2 if n < 0 else -(n+Qb//2) for n in k]
421
428
  for k in m] for m in z]