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.
@@ -11,9 +11,10 @@ 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
+ from matplotlib.colors import to_rgb
17
18
 
18
19
  logger = logging.getLogger(__name__)
19
20
 
@@ -58,7 +59,7 @@ def _integrate(radius, pos, val):
58
59
 
59
60
 
60
61
  def _integrate1d(radius, val):
61
- interp = interp1d(radius, val)
62
+ interp = make_interp_spline(radius, val, k=1)
62
63
  def func(x):
63
64
  return interp((x))
64
65
  return quad(func, radius[0], radius[-1])[0]
@@ -598,6 +599,280 @@ def _get_copper_losses(scale_factor, bch):
598
599
  return 0 # noload calc has no winding losses
599
600
 
600
601
 
602
+ def _set_plot_attributes(ax):
603
+ ax.set_aspect('equal')
604
+ for loc, spine in ax.spines.items():
605
+ spine.set_color('none') # don't draw spine
606
+ ax.yaxis.set_ticks([])
607
+ ax.xaxis.set_ticks([])
608
+
609
+
610
+ def _get_colors(colors, delta):
611
+ if delta == 0.0:
612
+ return colors
613
+ new_colors = []
614
+ for col in colors:
615
+ rgb = to_rgb(col)
616
+ r, g, b = rgb
617
+ col = (max(0.0, min(r+delta, 1.0)),
618
+ max(0.0, min(g+delta, 1.0)),
619
+ max(0.0, min(b+delta, 1.0)))
620
+ new_colors.append(col)
621
+ return new_colors
622
+
623
+
624
+ def _draw_vertical_magnets(ax,
625
+ poles,
626
+ xr, yr,
627
+ Rr,
628
+ xoff, yoff,
629
+ delta=0.0):
630
+ color = ['green', 'red']
631
+ color = _get_colors(color, delta)
632
+ for i in range(poles):
633
+ ax.fill(xr+xoff, yr+yoff,
634
+ facecolor=color[i%2], edgecolor=color[i%2])
635
+ xr, yr = np.dot(Rr, [xr, yr])
636
+ return
637
+
638
+
639
+ def _draw_vertical_slots(ax,
640
+ Q,
641
+ r,
642
+ alpha,
643
+ xoff, yoff,
644
+ delta=0.0):
645
+ color = ['skyblue', 'blue']
646
+ color = _get_colors(color, delta)
647
+ taus = 2*np.pi/Q
648
+ for n in range(Q):
649
+ beta = np.array([[n*taus+alpha[0], (n+1)*taus-alpha[0]],
650
+ [(n+1)*taus-alpha[1], n*taus+alpha[1]]])
651
+ ax.fill(np.hstack((r * np.cos(beta[0, 0]),
652
+ (r[::-1] * np.cos(beta[0, 1]))))+xoff,
653
+ np.hstack((r * np.sin(beta[0, 0]),
654
+ (r[::-1] * np.sin(beta[0, 1]))))+yoff,
655
+ facecolor=color[0], edgecolor=color[0])
656
+
657
+
658
+ def vertical_plot(machine, ax):
659
+ """plots afpm stator and rotor (vertical section)
660
+ Args:
661
+ dy1, dy1: float outer, inner diameter
662
+ rel_magn_width: float rel magnet width 0..1
663
+ Q: number of stator slots
664
+ poles: number of poles
665
+ slot_width: width of stator slot
666
+ """
667
+ logger.debug("begin of vertical_plot()")
668
+
669
+ model_type = machine['afmtype'][0:4]
670
+ dy1 = machine['outer_diam']*1e3
671
+ dy2 = machine['inner_diam']*1e3
672
+ rel_magn_width = machine['magnet']['afm_rotor']['rel_magn_width']
673
+ Q = machine['stator']['num_slots']
674
+ slot_width = machine['stator']['afm_stator']['slot_width']*1e3
675
+ poles = machine['poles']
676
+
677
+ # prepare Magnets
678
+ theta = np.linspace(np.pi/poles*(1-rel_magn_width),
679
+ np.pi/poles*(1+rel_magn_width),
680
+ 10)
681
+ xr = np.concatenate((dy1/2 * np.cos(theta), dy2/2 * np.cos(theta[::-1])))
682
+ yr = np.concatenate((dy1/2 * np.sin(theta), dy2/2 * np.sin(theta[::-1])))
683
+ rtheta = 2*np.pi/poles
684
+ Rr = np.array([
685
+ [np.cos(rtheta), -np.sin(rtheta)],
686
+ [np.sin(rtheta), np.cos(rtheta)]
687
+ ])
688
+
689
+ # prepare Slots
690
+ taus = 2*np.pi/Q
691
+ r = np.array([dy2/2, dy1/2])
692
+ alpha = np.arctan2(slot_width/2, r)
693
+
694
+ yoff = 0.0
695
+ xoff = 0.0
696
+ y_shift = -2
697
+ x_shift = dy1-dy2
698
+ ma_delta = 0.0 # color
699
+ sl_delta = 0.0 # color
700
+
701
+ # Draw
702
+ if model_type in ("S1R2"): # 2 rotor
703
+ _draw_vertical_magnets(ax, poles, xr, yr, Rr, xoff, yoff, delta=-0.1)
704
+ yoff += y_shift
705
+ xoff += x_shift
706
+
707
+ if model_type in ("S2R1"): # 2 stator
708
+ sl_delta = -0.1
709
+
710
+ _draw_vertical_slots(ax, Q, r, alpha, xoff, yoff, delta=sl_delta)
711
+ yoff += y_shift
712
+ xoff += x_shift
713
+
714
+ if model_type in ("S1R2"): # 2 rotor
715
+ ma_delta = 0.1
716
+
717
+ _draw_vertical_magnets(ax, poles, xr, yr, Rr, xoff, yoff, delta=ma_delta)
718
+ yoff += y_shift
719
+ xoff += x_shift
720
+
721
+ if model_type in ("S2R1"): # 2 stator
722
+ sl_delta = 0.0
723
+ _draw_vertical_slots(ax, Q, r, alpha, xoff, yoff, delta=sl_delta)
724
+
725
+ _set_plot_attributes(ax)
726
+ logger.debug("end of vertical_plot()")
727
+
728
+
729
+ IRON_NO = 0
730
+ IRON_UP = 1
731
+ IRON_DOWN = 2
732
+
733
+ def _draw_horizontal_magnets(ax,
734
+ poles,
735
+ magn_height,
736
+ magn_width,
737
+ yoke_height,
738
+ Q,
739
+ g,
740
+ taus,
741
+ dy2,
742
+ yoff=0.0,
743
+ iron=IRON_NO
744
+ ):
745
+ color = ['green', 'red']
746
+ xy = (0, Q//g*taus, Q//g*taus, 0)
747
+
748
+ if iron == IRON_UP:
749
+ yy = (yoff-yoke_height,
750
+ yoff-yoke_height,
751
+ yoff,
752
+ yoff)
753
+ yoff -= yoke_height
754
+ ax.fill(xy, yy, color='skyblue')
755
+
756
+ taum = dy2*np.pi/poles
757
+ ym = np.array([yoff-magn_height,
758
+ yoff-magn_height,
759
+ yoff,
760
+ yoff])
761
+ yoff -= magn_height
762
+
763
+ for n in range(poles//g):
764
+ xl = taum*n + taum*(1 - magn_width)
765
+ xr = taum*(n + 1) - taum*(1 - magn_width)
766
+ xm = (xl, xr, xr, xl)
767
+ ax.fill(xm, ym, color=color[n%2])
768
+
769
+ if iron == IRON_DOWN:
770
+ yy = (yoff-yoke_height,
771
+ yoff-yoke_height,
772
+ yoff,
773
+ yoff)
774
+ yoff -= yoke_height
775
+ ax.fill(xy, yy, color='skyblue')
776
+ return yoff
777
+
778
+
779
+ TOOTH_UP = 0
780
+ TOOTH_DOWN = 1
781
+ TOOTH_ONLY = 2
782
+
783
+
784
+ def _draw_horizontal_slots(ax,
785
+ slot_height, slot_width, yoke_height,
786
+ Q, g, taus,
787
+ yoff=0.0,
788
+ tooth=TOOTH_DOWN):
789
+ if not tooth == TOOTH_ONLY:
790
+ xx = (0, Q//g*taus, Q//g*taus, 0)
791
+ if tooth == TOOTH_DOWN:
792
+ yy = (yoff-yoke_height,
793
+ yoff-yoke_height,
794
+ yoff,
795
+ yoff)
796
+ else:
797
+ yy = (yoff-slot_height,
798
+ yoff-slot_height,
799
+ yoff-slot_height-yoke_height,
800
+ yoff-slot_height-yoke_height)
801
+ ax.fill(xx, yy, color='skyblue')
802
+
803
+ yt = (yoff-slot_height-yoke_height,
804
+ yoff-slot_height-yoke_height,
805
+ yoff, yoff)
806
+ for n in range(Q//g):
807
+ xt = np.array((n*taus, n*taus+(taus-slot_width)/2,
808
+ n*taus+(taus-slot_width)/2, n*taus))
809
+ ax.fill(xt, yt, color='skyblue')
810
+ xt += slot_width + (taus-slot_width)/2
811
+ ax.fill(xt, yt, color='skyblue')
812
+ return yoff - slot_height - yoke_height
813
+
814
+
815
+ def horizontal_plot(machine, ax):
816
+ logger.debug("begin of horizontal_plot()")
817
+
818
+ model_type = machine['afmtype'][0:4]
819
+ dy1 = machine['outer_diam']*1e3
820
+ dy2 = machine['inner_diam']*1e3
821
+ rel_magn_width = machine['magnet']['afm_rotor']['rel_magn_width']
822
+ magn_height = machine['magnet']['afm_rotor']['magn_height']*1e3
823
+ magn_yoke_height = machine['magnet']['afm_rotor']['yoke_height']*1e3
824
+
825
+ Q = machine['stator']['num_slots']
826
+ slot_width = machine['stator']['afm_stator']['slot_width']*1e3
827
+ poles = machine['poles']
828
+ m = 3
829
+ slot_height = machine['stator']['afm_stator']['slot_height']*1e3
830
+ if model_type in ('S2R1', 'S2R1_all'):
831
+ slot_height /= 2
832
+ yoke_height = machine['stator']['afm_stator']['yoke_height']*1e3
833
+ ag = machine['airgap']*1e3
834
+
835
+ g = np.gcd(Q, m*poles)//m
836
+ taus = dy2*np.pi/Q
837
+
838
+ yoff = 0.0
839
+ if model_type in ('S1R2', 'S1R2_all'): # 2 rotor
840
+ yoff = _draw_horizontal_magnets(ax, poles,
841
+ magn_height, rel_magn_width,
842
+ magn_yoke_height,
843
+ Q, g, taus, dy2,
844
+ yoff=yoff,
845
+ iron=IRON_UP)
846
+ yoff -= ag
847
+
848
+ tooth = TOOTH_ONLY if model_type in ('S1R2', 'S1R2_all') else TOOTH_DOWN
849
+ yoff = _draw_horizontal_slots(ax,
850
+ slot_height, slot_width, yoke_height,
851
+ Q, g, taus,
852
+ yoff=yoff,
853
+ tooth=tooth)
854
+ yoff -= ag
855
+
856
+ iron = IRON_DOWN if model_type in ('S1R1', 'S1R2', 'S1R2_all') else IRON_NO
857
+ yoff = _draw_horizontal_magnets(ax, poles,
858
+ magn_height, rel_magn_width,
859
+ magn_yoke_height,
860
+ Q, g, taus, dy2,
861
+ yoff=yoff,
862
+ iron=iron)
863
+ yoff -= ag
864
+
865
+ if model_type in ('S2R1', 'S2R1_all'): # 2 rotor
866
+ yoff = _draw_horizontal_slots(ax,
867
+ slot_height, slot_width, yoke_height,
868
+ Q, g, taus,
869
+ yoff=yoff,
870
+ tooth=TOOTH_UP)
871
+
872
+ _set_plot_attributes(ax)
873
+ logger.debug("end of horizontal_plot()")
874
+
875
+
601
876
  class AFPM:
602
877
  """Axial Flux PM
603
878
  Arguments:
@@ -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
 
@@ -366,7 +366,8 @@ def dqparident(workdir, engine, temp, machine,
366
366
  num_beta_steps: number of current steps (default 7 per quadrant)
367
367
  speed: rotor speed in 1/s (default 160/p)
368
368
  i1_max: maximum current in A rms (default approx 3*i1nom)
369
- period_frac: fraction of rotating angle (default 6)
369
+ period_frac: (int) fraction of rotating angle (default 6)
370
+ dqtype: (str) type of identification: 'ldq' (default), 'psidq'
370
371
  cmd: femag executable
371
372
  """
372
373
  import pathlib
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])
femagtools/plot/char.py CHANGED
@@ -333,10 +333,14 @@ def _plot_contour(speed, torque, z, ax, title='', levels=[],
333
333
  clippath = Path(_get_nT_boundary(x, y))
334
334
  patch = PathPatch(clippath, facecolor='none')
335
335
  ax.add_patch(patch)
336
- for c in cont.collections:
337
- c.set_clip_path(patch)
338
- for c in contf.collections:
339
- c.set_clip_path(patch)
336
+ try:
337
+ for c in cont.collections:
338
+ c.set_clip_path(patch)
339
+ for c in contf.collections:
340
+ c.set_clip_path(patch)
341
+ except AttributeError: # matplotlib >= 3.10
342
+ cont.set_clip_path(patch)
343
+ contf.set_clip_path(patch)
340
344
 
341
345
  if xscale > 1:
342
346
  def format_fn(tick_val, tick_pos):
@@ -367,9 +371,16 @@ def efficiency_map(rmap, ax=0, title='', clabel=True,
367
371
 
368
372
 
369
373
  def losses_map(rmap, ax=0, title='Losses Map / kW', clabel=True,
370
- cmap='YlOrRd', cbar=False):
374
+ cmap='YlOrRd', cbar=False, key='losses'):
375
+ """
376
+ plot losses map
377
+ Args:
378
+ rmap: (dict) result of efficiency_losses_map
379
+ key: (str) type of losses: 'plfe1', 'plfe2', 'plmag', 'plcu1', 'plcu2', 'plfric', 'losses';
380
+ """
381
+
371
382
  if ax == 0:
372
383
  fig, ax = plt.subplots(figsize=(12, 12))
373
- return _plot_contour(rmap['n'], rmap['T'], np.asarray(rmap['losses'])/1e3, ax,
374
- title=title, levels=14, clabel=clabel,
375
- cmap=cmap, cbar=cbar)
384
+ return _plot_contour(rmap['n'], rmap['T'], np.asarray(rmap[key])/1e3, ax,
385
+ title=title, levels=14, clabel=clabel,
386
+ cmap=cmap, cbar=cbar)
@@ -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)-np.mean(y) > 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]
femagtools/zmq.py CHANGED
@@ -147,7 +147,6 @@ class SubscriberTask(threading.Thread):
147
147
  def send_notify():
148
148
  logger.debug(f"Send loop: {SubscriberTask.notify_send_loop}")
149
149
  while SubscriberTask.notify_send_loop:
150
- logger.debug(f"Send data: {SubscriberTask.notify_send_header}")
151
150
  if 'progress_logger' in SubscriberTask.notify_send_header:
152
151
  # collect data from different threads
153
152
  SubscriberTask.notify_send_header.remove('progress_logger')
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: femagtools
3
- Version: 1.8.3
3
+ Version: 1.8.5
4
4
  Summary: Python API for FEMAG
5
5
  Author-email: Ronald Tanner <tar@semafor.ch>, Dapu Zhang <dzhang@gtisoft.com>, Beat Holm <hob@semafor.ch>, Günther Amsler <amg@semafor.ch>, Nicolas Mauchle <mau@semafor.ch>
6
6
  License: Copyright (c) 2016-2023, Semafor Informatik & Energie AG, Basel