femagtools 1.8.14__py3-none-any.whl → 1.8.16__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/__init__.py CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  """
4
4
  __title__ = 'femagtools'
5
- __version__ = '1.8.14'
5
+ __version__ = '1.8.16'
6
6
  __author__ = 'Ronald Tanner'
7
7
  __license__ = 'BSD'
8
8
  __copyright__ = 'Copyright 2023-2025 Gamma Technology'
femagtools/bch.py CHANGED
@@ -420,6 +420,11 @@ class Reader:
420
420
  self.windings[w[0]]['N'].append(w[2])
421
421
  self.windings[w[0]]['R'].append(w[3]/1e3)
422
422
  self.windings[w[0]]['PHI'].append(w[4])
423
+ # check if external rotor
424
+ if hasattr(self, "machine"):
425
+ if "fc_radius" in self.machine:
426
+ if np.mean(self.windings[1]["R"]) < self.machine["fc_radius"]:
427
+ self.external_rotor = True
423
428
 
424
429
  def __read_winding_factors(self, content):
425
430
  "read winding factors section"
@@ -1202,10 +1207,7 @@ class Reader:
1202
1207
  m = []
1203
1208
  subregs = [name.split()[-1]
1204
1209
  for name in content[2].split('\t') if name][2:]
1205
- # outer rotor motor
1206
- if 'Iron' in subregs and \
1207
- 'Rotor' in subregs:
1208
- self.external_rotor = True
1210
+
1209
1211
  logger.info("Stator Subregions: %s", subregs)
1210
1212
  speed = float(content[0].split()[-1])/60.
1211
1213
  logger.info('losses for speed %f', speed)
femagtools/femag.py CHANGED
@@ -153,7 +153,7 @@ class BaseFemag(object):
153
153
  dest = dir if dir else self.workdir
154
154
  if isinstance(feloss, (int, float)):
155
155
  try:
156
- feloss = {1: 'jordan', 11: 'bertotti'}[int(feloss)]
156
+ feloss = {1: 'jordan', 2: "steinmetz", 10:"modified steinmetz", 11: 'bertotti'}[int(feloss)]
157
157
  except KeyError:
158
158
  feloss = ''
159
159
  return [self.magnetizingCurves.writefile(m[0], dest,
@@ -188,6 +188,11 @@ class BaseFemag(object):
188
188
  recsin = simulation.get('recsin', '')
189
189
  feloss = simulation.get('calc_fe_loss', '')
190
190
  self.copy_magnetizing_curves(self.model, recsin=recsin, feloss=feloss)
191
+
192
+ if feloss and \
193
+ int(feloss) in (1, 2):
194
+ simulation["calc_fe_loss"] = 1
195
+
191
196
  try:
192
197
  if 'wdgdef' in self.model.winding:
193
198
  self.model.winding['wdgfile'] = self.create_wdg_def(
femagtools/fsl.py CHANGED
@@ -23,6 +23,15 @@ def cosys(model):
23
23
  return 'cosys("polar")'
24
24
  return 'cosys("cartes")'
25
25
 
26
+ class MaterialCollection:
27
+ def __init__(self, materials):
28
+ self.materials = materials
29
+
30
+ def find(self, name):
31
+ for mat in self.materials:
32
+ if mat['name'] == name:
33
+ return mat
34
+ return None
26
35
 
27
36
  class Builder:
28
37
  def __init__(self, templatedirs=[]):
@@ -922,4 +931,4 @@ class Builder:
922
931
  content='\n'.join(content),
923
932
  type='fsl',
924
933
  content_template='\n'.join(content_template),
925
- parameter=parameter)
934
+ parameter=parameter)
femagtools/isa7.py CHANGED
@@ -921,7 +921,7 @@ class Isa7(object):
921
921
  else:
922
922
  flx_fac = 1
923
923
  el_fe_ind = [np.array(reader.el_fe_induction_1).T/flx_fac,
924
- np.array(reader.el_fe_induction_2).T/flx_fac]
924
+ np.array(reader.el_fe_induction_2).T/flx_fac]
925
925
  eddy_cu_vpot = np.array(reader.eddy_cu_vpot).T/1000
926
926
  if len(el_fe_ind[0].shape) == 4:
927
927
  pdim = self.pos_el_fe_induction.shape[0]
@@ -1051,12 +1051,9 @@ class Isa7(object):
1051
1051
  slf = 1 #self.PS_FILFACTOR_CU[r]
1052
1052
  self.mass[r]['conductors'] += scf*se.area()*self.arm_length*spw*l*slf
1053
1053
  for se in self.superelements:
1054
- winding_detected=0
1055
- lamination_detected=0
1056
1054
  r = 0 if se.outside else 1
1057
1055
  if se.subregion:
1058
1056
  if se.subregion.winding:
1059
- winding_detected=1
1060
1057
  spw = self.CU_SPEZ_WEIGHT*1e3
1061
1058
  l = self.PS_LENGTH_CU[r]*1e-2
1062
1059
  slf = self.PS_FILFACTOR_CU[r]
@@ -1064,7 +1061,6 @@ class Isa7(object):
1064
1061
  continue
1065
1062
 
1066
1063
  if se.mcvtype or se.elements[0].is_lamination():
1067
- lamination_detected=1
1068
1064
  try:
1069
1065
  spw = self.iron_loss_coefficients[se.mcvtype-1][
1070
1066
  'spec_weight']*1e3 # kg/m³
@@ -1096,7 +1092,8 @@ class Isa7(object):
1096
1092
 
1097
1093
  """
1098
1094
  return [sr.name for sr in self.subregions
1099
- if sr.superelements[0].mcvtype or sr.superelements[0].elements[0].is_lamination()]
1095
+ if (sr.superelements[0].mcvtype or
1096
+ sr.superelements[0].elements[0].is_lamination())]
1100
1097
 
1101
1098
  def _axis_ratio(self, apos, br, bt):
1102
1099
  from .utils import fft
@@ -1399,6 +1396,23 @@ class Isa7(object):
1399
1396
  bxy.append(Trot(-theta).dot((fd['bx'], fd['by'])))
1400
1397
  return transform_flux_density(se.alpha, np.array(bxy))
1401
1398
 
1399
+ def lamination_border(self):
1400
+ """return xy coordinates of lamination border nodes"""
1401
+ bnodes = []
1402
+ for sr in self.get_iron_subregions():
1403
+ #bnodes += self.get_subregion(sr).border_node_keys()
1404
+ bnodes += self.get_subregion(sr).nonper_border_nodes()[1]
1405
+ keys, unique_counts = np.unique(bnodes, return_counts=True)
1406
+
1407
+ return np.array([self.nodes[k-1].xy
1408
+ for k, c in zip(keys, unique_counts) if c == 1])
1409
+
1410
+ def punchdist(self):
1411
+ """ return lamination elements with punching border distance"""
1412
+ elam = [e for e in self.elements if e.is_lamination()]
1413
+ bnodes = self.lamination_border()
1414
+ return elam, np.array([e.punchdist(bnodes) for e in elam])
1415
+
1402
1416
  class Point(object):
1403
1417
  def __init__(self, x, y):
1404
1418
  self.x = x
@@ -1495,7 +1509,8 @@ class Element(BaseEntity):
1495
1509
  [v.xy for v in vertices], axis=0)/len(vertices)
1496
1510
 
1497
1511
  def flux_density(self, cosys='cartes'):
1498
- """return flux density components of this element converted to cosys: cartes, cylind, polar"""
1512
+ """return flux density components of this element converted
1513
+ to cosys: cartes, cylind, polar"""
1499
1514
  ev = self.vertices
1500
1515
  b1, b2 = 0, 0
1501
1516
  if self.el_type == ElType.LinearTriangle:
@@ -1621,6 +1636,16 @@ class Element(BaseEntity):
1621
1636
  """return temperature of this element"""
1622
1637
  return sum([v.vpot[1] for v in self.vertices])/len(self.vertices)
1623
1638
 
1639
+ def punchdist(self, bnodes):
1640
+ """return dist to punching border"""
1641
+ try:
1642
+ if self.is_lamination():
1643
+ return np.min(np.linalg.norm(bnodes-self.center,
1644
+ axis=1))
1645
+ except AttributeError:
1646
+ pass
1647
+ return np.nan
1648
+
1624
1649
 
1625
1650
  class SuperElement(BaseEntity):
1626
1651
  def __init__(self, key, sr_key, elements, nodechains, color,
@@ -1704,6 +1729,7 @@ class SubRegion(BaseEntity):
1704
1729
  for se in superelements:
1705
1730
  se.subregion = self
1706
1731
  self.nodechains = nodechains
1732
+ self._border = []
1707
1733
 
1708
1734
  def elements(self):
1709
1735
  """return elements of this subregion"""
@@ -1716,6 +1742,12 @@ class SubRegion(BaseEntity):
1716
1742
  """return area of this subregion"""
1717
1743
  return sum([e.area for e in self.elements()])
1718
1744
 
1745
+ def nonper_border_nodes(self):
1746
+ """return border nodes with non-periodic boundary condition"""
1747
+ return (np.array([n.xy for nc in self.nodechains
1748
+ for n in nc.nodes if n.pernod == 0]),
1749
+ set([n.key for nc in self.nodechains
1750
+ for n in nc.nodes if n.pernod == 0]))
1719
1751
 
1720
1752
  class Winding(BaseEntity):
1721
1753
  def __init__(self, key, name, subregions, num_turns, cur_re, cur_im,
@@ -213,6 +213,9 @@ def parident(workdir, engine, temp, machine,
213
213
  if np.isscalar(machine['magnet'][slotmodel]['rel_magn_width']):
214
214
  num_slices = kwargs.get('num_slices', 3)
215
215
  rmagw = num_slices*[machine['magnet'][slotmodel]['rel_magn_width']]
216
+ elif len(machine['magnet'][slotmodel]['rel_magn_width']) == 1:
217
+ num_slices = kwargs.get('num_slices', 3)
218
+ rmagw = num_slices*machine['magnet'][slotmodel]['rel_magn_width']
216
219
  else:
217
220
  rmagw = machine['magnet'][slotmodel]['rel_magn_width']
218
221
  num_slices = len(rmagw)
@@ -543,13 +546,18 @@ def process(lfe, pole_width, machine, bch):
543
546
  nsegx = machine['magnet'].get('num_segments', 1)
544
547
  if type(nsegx) == int:
545
548
  nsegx = [nsegx]*len(bch)
549
+ elif len(nsegx) == 1 and len(nsegx) < len(bch):
550
+ nsegx = nsegx*len(bch)
551
+ else:
552
+ pass
546
553
  for nx, b in zip(nsegx, bch):
547
554
  pm = b['losses'][0]['magnet_data']
548
555
  magloss = ecloss.MagnLoss(magnet_data=[pm])
549
556
  ml = magloss.calc_losses_ialh2(nsegx=nx)
550
- b['losses'][-1][k] = ml[0]
557
+ b["losses"][-1].update({k: ml[0]})
551
558
  else:
552
559
  k = 'magnetJ'
560
+
553
561
  if len(pole_width) > 1:
554
562
  maglosses = _integrate1d(radius, scale_factor*np.array(
555
563
  [b['losses'][-1][k]/lz
@@ -1025,7 +1033,9 @@ class AFPM:
1025
1033
  machine['magnet'][slotmodel]['rel_magn_width'])
1026
1034
  if np.isscalar(machine['magnet'][slotmodel]['rel_magn_width']):
1027
1035
  rmagw = num_slices*[machine['magnet'][slotmodel]['rel_magn_width']]
1028
- else:
1036
+ elif len(machine['magnet'][slotmodel]['rel_magn_width']) == 1:
1037
+ rmagw = num_slices*machine['magnet'][slotmodel]['rel_magn_width']
1038
+ else:
1029
1039
  rmagw = machine['magnet'][slotmodel]['rel_magn_width']
1030
1040
  num_slices = len(rmagw)
1031
1041
 
@@ -79,7 +79,11 @@ def iqd_tmech_umax_multi(num_proc, ntmesh, m, u1, with_mtpa, with_tmech,
79
79
  while progress_readers:
80
80
  for r in multiprocessing.connection.wait(progress_readers):
81
81
  try:
82
- collected_msg.append(r.recv())
82
+ #collected_msg.append(r.recv())
83
+ ret = r.recv()
84
+ if isinstance(ret, Exception):
85
+ raise ret
86
+ collected_msg.append(ret)
83
87
  i += 1
84
88
  except EOFError:
85
89
  progress_readers.remove(r)
@@ -263,10 +267,11 @@ def efficiency_losses_map(eecpars, u1, T, temp, n, npoints=(60, 40),
263
267
  if isinstance(m, (SynchronousMachineLdq, SynchronousMachinePsidq)):
264
268
  iq, id, iex = m.iqd_torque(T[-1])
265
269
  i1max = betai1(iq, id)[1]
266
- w1type, tmax = m.w1_imax_umax(i1max, u1)
270
+ w1type, tmax = m.w1_imax_umax(i1max, u1)
267
271
  pmax = tmax*w1type/m.p
268
272
  else:
269
273
  iq, id = m.iqd_torque(T[-1])
274
+ w1type, tmax = m.w1_imax_umax(betai1(iq, id)[1], u1)
270
275
 
271
276
  i1max = betai1(iq, id)[1]
272
277
  logger.info("%s %s", n, T)
@@ -274,16 +279,19 @@ def efficiency_losses_map(eecpars, u1, T, temp, n, npoints=(60, 40),
274
279
  w1 = 2*np.pi*nx*m.p
275
280
  if isinstance(m, (SynchronousMachineLdq, SynchronousMachinePsidq)):
276
281
  tq = T[-1]
277
- if tq*w1/m.p > pmax:
282
+ if tq*w1/m.p > pmax:
278
283
  tq = pmax/w1*m.p
279
284
  else:
280
- iq, id, tq = m.iqd_imax_umax(i1max, w1, u1, T[-1],
281
- with_tmech=with_tmech,
282
- with_mtpa=with_mtpa)
285
+ if w1 <= w1type:
286
+ tq = tmax
287
+ else:
288
+ iq, id, tq = m.iqd_imax_umax(i1max, w1, u1, T[-1],
289
+ with_tmech=with_tmech,
290
+ with_mtpa=with_mtpa)
283
291
  if np.isclose(tq, T[-1]):
284
292
  tq = T[-1]
285
293
  for Tx in T:
286
- if Tx <= tq:
294
+ if np.abs(Tx) <= tq:
287
295
  nt.append((nx, Tx))
288
296
  if not nt:
289
297
  raise ValueError("Speed, Torque Mesh is empty")
@@ -339,7 +347,7 @@ def efficiency_losses_map(eecpars, u1, T, temp, n, npoints=(60, 40),
339
347
  else:
340
348
  f1 = []
341
349
  u1max = u1
342
- r = dict(u1=[], i1=[], plfe1=[], plcu1=[], plcu2=[])
350
+ r = dict(u1=[], i1=[], plfe1=[], plcu1=[], plcu2=[], plcu1_dc=[], plcu1_ac=[])
343
351
  for nx, tq in ntmesh.T:
344
352
  wm = 2*np.pi*nx
345
353
  w1 = m.w1(u1max, m.psiref, tq, wm)
@@ -352,7 +360,9 @@ def efficiency_losses_map(eecpars, u1, T, temp, n, npoints=(60, 40),
352
360
  i2 = m.i2(w1, m.psi, wm)
353
361
  r['plcu1'].append(m.m*np.abs(i1)**2*m.rstat(w1))
354
362
  r['plcu2'].append(m.m*np.abs(i2)**2*m.rrot(w1-m.p*wm))
355
-
363
+ plcu_dc = m.m*np.abs(i1)**2*m.rstat(0)
364
+ r['plcu1_dc'].append(plcu_dc)
365
+ r['plcu1_ac'].append(m.m*np.abs(i1)**2*m.rstat(w1)-plcu_dc)
356
366
  if isinstance(m, PmRelMachine):
357
367
  plfe1 = m.kpfe*m.iqd_plfe1(*iqd, f1)
358
368
  plfe2 = m.kpfe*m.iqd_plfe2(iqd[0], iqd[1], f1)
@@ -370,7 +380,7 @@ def efficiency_losses_map(eecpars, u1, T, temp, n, npoints=(60, 40),
370
380
  plfe1 = m.kpfe*m.iqd_plfe1(*iqd, f1)
371
381
  plfe2 = m.kpfe*m.iqd_plfe2(*iqd, f1)
372
382
  plmag = np.zeros_like(plfe2)
373
- plcu1 = m.iqd_plcu1(iqd[0], iqd[1], 2*np.pi*f1)
383
+ plcu1 = m.iqd_plcu1(iqd[0], iqd[1], f1)
374
384
  try:
375
385
  plcu1_dc = m.iqd_plcu1(iqd[0], iqd[1],
376
386
  np.array([0.0 for i in f1])).tolist()
@@ -388,19 +398,22 @@ def efficiency_losses_map(eecpars, u1, T, temp, n, npoints=(60, 40),
388
398
  plmag = np.zeros(ntmesh.shape[1])
389
399
  plcu1 = np.array(r['plcu1'])
390
400
  plcu2 = np.array(r['plcu2'])
391
- plcu1_dc = [] # reserved for winding (dc, ac) losses
392
- plcu1_ac = []
401
+ plcu1_dc = r['plcu1_dc'] # [] # reserved for winding (dc, ac) losses
402
+ plcu1_ac = r['plcu1_ac'] #[]
393
403
  iqd = np.zeros(ntmesh.shape)
394
404
  u1 = np.array(r['u1'])
395
405
  i1 = np.array(r['i1'])
406
+
407
+
396
408
  try:
397
409
  if isinstance(eecpars, dict):
398
410
  tfric = eecpars['kfric_b']*eecpars['rotor_mass']*30e-3/np.pi
411
+ if 'tfric' in eecpars: # to get the user setted value (possible in IM)
412
+ tfric=eecpars['tfric']
399
413
  else:
400
414
  tfric = m.tfric
401
415
  except KeyError:
402
416
  tfric = 0
403
-
404
417
  plfric = 2*np.pi*ntmesh[0]*tfric
405
418
  if not with_tmech:
406
419
  ntmesh[1] -= tfric
@@ -437,4 +450,4 @@ def efficiency_losses_map(eecpars, u1, T, temp, n, npoints=(60, 40),
437
450
  plfric=plfric.tolist(),
438
451
  losses=ploss.tolist(),
439
452
  plcu1_dc=plcu1_dc,
440
- plcu1_ac=plcu1_ac)
453
+ plcu1_ac=plcu1_ac)
femagtools/machine/im.py CHANGED
@@ -198,7 +198,9 @@ class InductionMachine(Component):
198
198
 
199
199
  def lstat(self, w):
200
200
  """stator leakage inductance"""
201
- return self.lsigma1
201
+ # we add end-winding inductance here
202
+ le_value = getattr(self, 'le', 0)
203
+ return self.lsigma1 + le_value
202
204
 
203
205
  def rrot(self, w):
204
206
  """rotor resistance"""
@@ -485,77 +487,81 @@ class InductionMachine(Component):
485
487
  """
486
488
  with_tmech = kwargs.get('with_tmech', True)
487
489
 
488
- wmType = self.wmfweak(u1max, self.psiref, T, with_tmech)
489
- pmmax = wmType*T
490
- wmPullout = so.fsolve(
491
- lambda wx: (kpo*self.pullouttorque(self.p *
492
- wx, u1max) - abs(pmmax/wx)),
493
- wmType)[0]
494
- wmtab0 = np.linspace(wmType, 3*wmPullout)
495
- for wm, tq in zip(wmtab0, [pmmax/wx for wx in wmtab0]):
496
- logger.debug("u1 %g psi %g tq %g wm %g",
497
- u1max, self.psiref, tq, wm)
498
- try:
499
- w1 = self.w1(u1max, self.psiref, tq, wm, with_tmech)
500
- except ValueError:
501
- wmPullout = wm
502
- break
503
- wmMax = max(1.5*wmPullout, 3*abs(pmmax/T))
504
- if n:
505
- wmMax = 2*np.pi*n
506
- if wmMax > wmPullout:
507
- wmtab0 = np.linspace(wmPullout, wmMax)
508
- for wm, tq in zip(wmtab0, [pmmax/wx**2
509
- for wx in wmtab0]):
490
+ if np.isscalar(T):
491
+ wmType = self.wmfweak(u1max, self.psiref, T, with_tmech)
492
+ logger.info(wmType)
493
+ pmmax = wmType*T
494
+ wmPullout = so.fsolve(
495
+ lambda wx: (kpo*self.pullouttorque(self.p *
496
+ wx, u1max) - abs(pmmax/wx)),
497
+ wmType)[0]
498
+ wmtab0 = np.linspace(wmType, 3*wmPullout)
499
+ for wm, tq in zip(wmtab0, [pmmax/wx for wx in wmtab0]):
510
500
  logger.debug("u1 %g psi %g tq %g wm %g",
511
- u1max, self.psiref, tq, wm)
501
+ u1max, self.psiref, tq, wm)
512
502
  try:
513
503
  w1 = self.w1(u1max, self.psiref, tq, wm, with_tmech)
514
504
  except ValueError:
515
- wmMax = wm
505
+ wmPullout = wm
516
506
  break
517
-
518
- logger.info("wmtype %f wpo %f wmmax %f", wmType, wmPullout, wmMax)
519
-
520
- if wmType < wmPullout < wmMax:
521
- wmrange = sorted([0, wmType, wmPullout, wmMax])
522
- elif wmMax < wmType:
523
- wmrange = sorted([0, wmMax])
524
- elif wmType<0 or wmPullout<0 or wmMax<0:
525
- wmrange = sorted([1, abs(min(wmMax,wmType, wmPullout)), abs(max(wmMax,wmType, wmPullout))])
526
- else:
527
- wmrange = sorted([0, wmType, wmMax])
528
- logger.info("Speed range %s", wmrange)
529
- wmlin = []
530
- dw = 0
531
- for i, nx in enumerate([round(nsamples*(w1-w0)/wmMax)
532
- for w1, w0 in zip(wmrange[1:],
533
- wmrange)]):
534
- if nx == 1:
535
- nx = 2
536
- if nx > 0:
537
- lw = np.linspace(wmrange[i]+dw, wmrange[i+1], nx)
538
- dw = lw[-1] - lw[-2]
539
- wmlin.append(lw)
540
- if len(wmlin) > 1:
541
- wmtab = np.concatenate(wmlin)
542
- else:
543
- wmtab = wmlin[1:]
544
-
545
- def tload2(wm):
546
- if wm < wmType and wm < wmPullout:
547
- return T
548
- if wm < wmPullout:
507
+ wmMax = max(1.5*wmPullout, 3*abs(pmmax/T))
508
+ if n:
509
+ wmMax = 2*np.pi*n
510
+ if wmMax > wmPullout:
511
+ wmtab0 = np.linspace(wmPullout, wmMax)
512
+ for wm, tq in zip(wmtab0, [pmmax/wx**2
513
+ for wx in wmtab0]):
514
+ logger.debug("u1 %g psi %g tq %g wm %g",
515
+ u1max, self.psiref, tq, wm)
516
+ try:
517
+ w1 = self.w1(u1max, self.psiref, tq, wm, with_tmech)
518
+ except ValueError:
519
+ wmMax = wm
520
+ break
521
+
522
+ logger.info("wmtype %f wpo %f wmmax %f", wmType, wmPullout, wmMax)
523
+
524
+ if wmType < wmPullout < wmMax:
525
+ wmrange = sorted([0, wmType, wmPullout, wmMax])
526
+ elif wmMax < wmType:
527
+ wmrange = sorted([0, wmMax])
528
+ elif wmType<0 or wmPullout<0 or wmMax<0:
529
+ wmrange = sorted([1, abs(min(wmMax,wmType, wmPullout)), abs(max(wmMax,wmType, wmPullout))])
530
+ else:
531
+ wmrange = sorted([0, wmType, wmMax])
532
+ logger.info("Speed range %s", wmrange)
533
+ wmlin = []
534
+ dw = 0
535
+ for i, nx in enumerate([round(nsamples*(w1-w0)/wmMax)
536
+ for w1, w0 in zip(wmrange[1:],
537
+ wmrange)]):
538
+ if nx == 1:
539
+ nx = 2
540
+ if nx > 0:
541
+ lw = np.linspace(wmrange[i]+dw, wmrange[i+1], nx)
542
+ dw = lw[-1] - lw[-2]
543
+ wmlin.append(lw)
544
+ if len(wmlin) > 1:
545
+ wmtab = np.concatenate(wmlin)
546
+ else:
547
+ wmtab = wmlin[1:]
548
+
549
+ def tload2(wm):
550
+ if wm < wmType and wm < wmPullout:
551
+ return T
552
+ if wm < wmPullout:
553
+ if pmmax < 0:
554
+ return max(T, pmmax/wm)
555
+ return min(T, pmmax/wm)
549
556
  if pmmax < 0:
550
- return max(T, pmmax/wm)
551
- return min(T, pmmax/wm)
552
- if pmmax < 0:
553
- return max(wmPullout*pmmax/wm**2, T)
554
- return min(wmPullout*pmmax/wm**2, T)
557
+ return max(wmPullout*pmmax/wm**2, T)
558
+ return min(wmPullout*pmmax/wm**2, T)
555
559
 
560
+ T = [tload2(wx) for wx in wmtab]
561
+ else:
562
+ wmtab = n
556
563
  r = dict(u1=[], i1=[], T=[], cosphi=[], n=[], s=[], sk=[],
557
- plfe1=[], plcu1=[], plcu2=[], f1=[])
558
- T = [tload2(wx) for wx in wmtab]
564
+ plfe1=[], plcu1=[], plcu2=[], f1=[])
559
565
  tfric = self.tfric
560
566
  with warnings.catch_warnings():
561
567
  warnings.simplefilter("ignore")
@@ -582,7 +588,8 @@ class InductionMachine(Component):
582
588
  r['s'].append(float((w1 - self.p * wm) / w1))
583
589
  r['sk'].append(self.sk(w1, np.abs(u1)/w1))
584
590
  # add n_type to result dict
585
- r['n_type'] = wmType/2/np.pi
591
+ if np.isscalar(T):
592
+ r['n_type'] = wmType/2/np.pi
586
593
  # except ValueError as ex:
587
594
  # break
588
595
  r['plfw'] = [self.pfric(n) for n in r['n']]
@@ -863,9 +870,11 @@ def parident(workdir, engine, f1, u1, wdgcon,
863
870
  # TODO: sigma = 58e6
864
871
  # if 'material' in machine[wdgk]:
865
872
  # sigma = condMat[machine[wdgk]]['elconduct']
873
+ if 'material' in m['windings']:
874
+ sigma = m['windings']['cuconduct']
866
875
  g = loadsim['num_par_wdgs']
867
876
  r1 = wdg_resistance(
868
- wdg, n, g, aw, da1, hs, lfe)
877
+ wdg, n, g, aw, da1, hs, lfe, sigma=sigma)
869
878
 
870
879
  # psi1 = ip.interp1d(i1_0, np.mean(psi1_0, axis=1),
871
880
  # kind='quadratic')
@@ -910,7 +919,7 @@ def parident(workdir, engine, f1, u1, wdgcon,
910
919
  # ls2 = results[1]['ls2']
911
920
  pfe = results[2]['pfe1'][0]
912
921
 
913
- end_ring_section = machine['rotor']['Aring']
922
+ end_ring_section = machine['rotor'].get('Aring', 0)
914
923
  bore_diam = machine['bore_diam']
915
924
  for key, value in machine['rotor'].items():
916
925
  if isinstance(value, dict) and 'slot_height' in value:
@@ -957,12 +966,15 @@ def parident(workdir, engine, f1, u1, wdgcon,
957
966
  wmat = machine[wdgk]['material']
958
967
  impars['kth1'] = parstudy.femag.condMat.find(wmat)['tempcoef']
959
968
  except KeyError:
960
- logger.warning('Missing winding material id')
969
+ logger.warning('Missing winding material id for stator')
970
+ for mat in condMat:
971
+ if mat['name'] == 'Cu': #as Copper is used as default (cf r1 and wdg_resistance)
972
+ impars['kth1'] = mat['tempcoef']
961
973
  try:
962
974
  bmat = machine['rotor']['material']
963
975
  impars['kth2'] = parstudy.femag.condMat.find(bmat)['tempcoef']
964
976
  except KeyError:
965
- logger.warning('Missing winding material id')
977
+ logger.warning('Missing winding material id for rotor')
966
978
 
967
979
  return impars
968
980
 
femagtools/machine/sm.py CHANGED
@@ -341,7 +341,6 @@ class SynchronousMachine(object):
341
341
  'stteeth_excess':1.5,
342
342
  'rotor_excess': 1.5})
343
343
 
344
-
345
344
  def pfric(self, n):
346
345
  """friction and windage losses"""
347
346
  return 2*np.pi*n*self.tfric
@@ -459,6 +458,13 @@ class SynchronousMachine(object):
459
458
  #options={'disp': disp, 'maxiter': maxiter})
460
459
  if res['success']:
461
460
  return res.x
461
+ else:
462
+ res = so.minimize(
463
+ lambda cur: (self.tmech_iqd(*cur, n) - torque)**2, res.x, method='SLSQP',
464
+ bounds=self.bounds,
465
+ )
466
+ if res['success']:
467
+ return res.x
462
468
 
463
469
  logger.warning("%s: torque=%f %f, io=%s",
464
470
  res['message'], torque, self.tmech_iqd(*startvals, n),
@@ -542,10 +548,29 @@ class SynchronousMachine(object):
542
548
  log(res.x)
543
549
  if res["success"]:
544
550
  return *res.x, self.tmech_iqd(*res.x, n)
551
+ else:
552
+ # didn't converge, fullfill voltage and torque demand
553
+ res = so.minimize(
554
+ lambda cur: (self.tmech_iqd(*cur, n) - torque)**2, io, method='SLSQP',
555
+ bounds=self.bounds,
556
+ constraints=[
557
+ {'type': 'eq',
558
+ 'fun': lambda iqd: np.linalg.norm(
559
+ self.uqd(w1, *iqd)) - u1max*np.sqrt(2)}]
560
+ )
561
+ if res["success"]:
562
+ return *res.x, self.tmech_iqd(*res.x, n)
563
+ else:
564
+ res = so.minimize(
565
+ lambda cur: (self.tmech_iqd(*cur, n) - torque)**2 +
566
+ (np.linalg.norm(self.uqd(w1, *cur)) - u1max*np.sqrt(2))**2, io, method='SLSQP',
567
+ bounds=self.bounds,
568
+ )
569
+ return *res.x, self.tmech_iqd(*res.x, n)
545
570
 
546
- logger.warning("%s: w1=%f torque=%f, u1max=%f, io=%s",
547
- res['message'], w1, torque, u1max, io)
548
- raise ValueError(res['message'])
571
+ # logger.warning("%s: w1=%f torque=%f, u1max=%f, io=%s",
572
+ # res['message'], w1, torque, u1max, io)
573
+ # raise ValueError(res['message'])
549
574
 
550
575
  def iqd_torque_umax(self, torque, w1, u1max,
551
576
  disp=False, maxiter=500, log=0, **kwargs):
@@ -622,6 +647,7 @@ class SynchronousMachine(object):
622
647
  """
623
648
  if kwargs.get('i1max', 0):
624
649
  w1type, T = self.w1_imax_umax(kwargs['i1max'], u1max)
650
+
625
651
  try:
626
652
  iq, id, iex = self.iqd_torque(T)
627
653
  except ValueError:
@@ -689,13 +715,17 @@ class SynchronousMachine(object):
689
715
  r['n_type'] = wmType/2/np.pi
690
716
  for wm, tq in zip(wmtab, [tload(wx) for wx in wmtab]):
691
717
  w1 = wm*self.p
692
- if with_tmech:
693
- iq, id, iex, tqx = self.iqd_tmech_umax(
694
- tq, w1, u1max)
695
- else:
696
- iq, id, iex, tqx = self.iqd_torque_umax(
697
- tq, w1, u1max)
698
- tqx -= self.tfric
718
+ if wm > wmType:
719
+ if with_tmech:
720
+ iq, id, iex, tqx = self.iqd_tmech_umax(
721
+ tq, w1, u1max)
722
+ else:
723
+ iq, id, iex, tqx = self.iqd_torque_umax(
724
+ tq, w1, u1max)
725
+ tqx -= self.tfric
726
+ else:
727
+ tqx = Tf
728
+
699
729
  uq, ud = self.uqd(w1, iq, id, iex)
700
730
  u1 = np.linalg.norm((uq, ud))/np.sqrt(2)
701
731
  f1 = w1/2/np.pi
@@ -708,7 +738,7 @@ class SynchronousMachine(object):
708
738
  beta -= 2*np.pi
709
739
  i1 = np.linalg.norm((id, iq), axis=0)/np.sqrt(2.0)
710
740
  r['i1'].append(i1)
711
- r['beta'].append(beta/180*np.pi)
741
+ r['beta'].append(beta/np.pi*180)
712
742
  gamma = np.arctan2(ud, uq)
713
743
  r['cosphi'].append(np.cos(gamma - beta))
714
744
  r['plfe1'].append(self.iqd_plfe1(iq, id, iex, f1))
@@ -826,7 +856,10 @@ class SynchronousMachinePsidq(SynchronousMachine):
826
856
  'styoke_eddy', 'stteeth_eddy',
827
857
  'rotor_hyst', 'rotor_eddy')}
828
858
 
829
-
859
+ def set_max_iex(self, iexc):
860
+ self.bounds[-1] = (self.bounds[-1][0], iexc)
861
+ self.exc_max = iexc
862
+
830
863
  def psi(self, iq, id, iex):
831
864
  """return psid, psiq of currents iq, id"""
832
865
  try:
@@ -947,6 +980,10 @@ class SynchronousMachineLdq(SynchronousMachine):
947
980
  'styoke_eddy', 'stteeth_eddy',
948
981
  'rotor_hyst', 'rotor_eddy')}
949
982
  pass
983
+
984
+ def set_max_iex(self, iexc):
985
+ self.bounds[-1] = (self.bounds[-1][0], iexc)
986
+ self.exc_max = iexc
950
987
 
951
988
  def psi(self, iq, id, iex):
952
989
  """return psid, psiq of currents iq, id"""
femagtools/plot/char.py CHANGED
@@ -306,11 +306,18 @@ def _plot_contour(speed, torque, z, ax, title='', levels=[],
306
306
  if not levels:
307
307
  if max(z) <= 1:
308
308
  if max(z) > 0.96:
309
- levels = [0.5, 0.75, 0.8, 0.84,
310
- 0.89, 0.92, 0.94, 0.96, 0.97]
309
+ #levels = [0.5, 0.75, 0.8, 0.84,
310
+ #0.89, 0.92, 0.94, 0.96, 0.97]
311
+ levels = np.linspace(min(z),max(z),9)
312
+ levels = np.round(levels, 2)
313
+ levels = list(levels)
314
+
311
315
  else:
312
- levels = [0.25, 0.5, 0.75, 0.8, 0.84,
313
- 0.88, 0.9, 0.92, 0.94, 0.96]
316
+ #levels = [0.25, 0.5, 0.75, 0.8, 0.84,
317
+ #0.88, 0.9, 0.92, 0.94, 0.96]
318
+ levels = np.linspace(min(z),max(z),9)
319
+ levels = np.round(levels, 2)
320
+ levels = list(levels)
314
321
 
315
322
  if max(z) > levels[-1]:
316
323
  levels.append(np.ceil(max(z)*100)/100)
@@ -376,7 +383,7 @@ def losses_map(rmap, ax=0, title='Losses Map / kW', clabel=True,
376
383
  plot losses map
377
384
  Args:
378
385
  rmap: (dict) result of efficiency_losses_map
379
- key: (str) type of losses: 'plfe1', 'plfe2', 'plmag', 'plcu1', 'plcu2', 'plfric', 'losses';
386
+ key: (str) type of losses: 'losses', 'plfe1', 'plfe2', 'plmag', 'plcu1', 'plcu1_dc', 'plcu1_ac', 'plcu2', 'plfric';
380
387
  """
381
388
 
382
389
  if ax == 0:
femagtools/plot/nc.py CHANGED
@@ -326,3 +326,12 @@ def temperature_distribution(isa, ax=0, cmap='plasma'):
326
326
  ctr = ctr + 1
327
327
  temp.append(tmp/ctr)
328
328
  _contour(ax, 'Temperature in K', elements, temp, '', cmap)
329
+
330
+ def punchdist(isa, cmap=DEFAULT_CMAP, ax=0):
331
+ """plot punching border distances of NC/I7/ISA7 model
332
+ Args:
333
+ isa: Isa7/NC object
334
+ """
335
+ elam, pdist = isa.punchdist()
336
+ _contour(ax, 'Punching Border Distances / mm)',
337
+ elam, pdist*1e3, 'mm', cmap, isa)
femagtools/plot/wdg.py CHANGED
@@ -7,6 +7,7 @@
7
7
  """
8
8
  import numpy as np
9
9
  import matplotlib.pyplot as plt
10
+ import logging
10
11
 
11
12
 
12
13
  def currdist(wdg, title='', k='all', phi=0, ax=0):
@@ -81,13 +82,13 @@ def mmf_fft(f, title='', mmfmin=1e-2, ax=0):
81
82
  pass
82
83
 
83
84
 
84
- def zoneplan(wdg, write_title=True, max_slots=0, ax=0):
85
+ def zoneplan(wdg, write_title=True, ax=0, max_slots=0):
85
86
  """plot zone plan of winding wdg"""
86
87
  from matplotlib.patches import Rectangle
87
88
  upper, lower = wdg.zoneplan()
88
89
  Qb = len([n for l in upper for n in l])
89
90
  if max_slots:
90
- Qb = max_slots
91
+ Qb = min(max_slots, Qb)
91
92
  from femagtools.windings import coil_color
92
93
  h = 0.5
93
94
  w = 1
@@ -171,7 +172,7 @@ def winding_factors(wdg, n=8, ax=0):
171
172
  pass
172
173
 
173
174
 
174
- def winding(wdg, ax=0):
175
+ def winding(wdg, ax=0, max_slots=0):
175
176
  """plot coils of windings wdg"""
176
177
  from matplotlib.patches import Rectangle
177
178
  from matplotlib.lines import Line2D
@@ -186,12 +187,16 @@ def winding(wdg, ax=0):
186
187
  if ax == 0:
187
188
  ax = plt.gca()
188
189
  z = wdg.zoneplan()
190
+ z0 = z[0] if len(z[0]) >= len(z[1]) else z[1]
191
+ Qb = sum([len(l) for l in z0])
192
+ if max_slots:
193
+ Qb = min(max_slots, Qb)
189
194
  xoff = 0
190
195
  if z[-1]:
191
196
  xoff = 0.75
192
197
  yd = dslot*wdg.yd
193
198
  mh = 2*coil_height/yd
194
- slots = sorted([abs(n) for m in z[0] for n in m])
199
+ slots = sorted([abs(n) for m in z[0] for n in m])[:Qb]
195
200
  smax = slots[-1]*dslot
196
201
  for n in slots: # draw slots and lamination
197
202
  x = n*dslot
@@ -204,6 +209,15 @@ def winding(wdg, ax=0):
204
209
  backgroundcolor="white",
205
210
  bbox=dict(boxstyle='circle,pad=0', fc="white", lw=0))
206
211
 
212
+ # colors in slots
213
+ csl = [['']*(Qb+1), ['']*(Qb+1)]
214
+ for i, layer in enumerate(z):
215
+ for m, mslots in enumerate(layer):
216
+ for k in mslots:
217
+ if abs(k) > Qb:
218
+ continue
219
+ csl[i][abs(k)-1] = coil_color[m]
220
+
207
221
  nl = 2 if z[1] else 1
208
222
  line_thickness = [0.6, 1.2]
209
223
  for i, layer in enumerate(z):
@@ -213,8 +227,9 @@ def winding(wdg, ax=0):
213
227
  d = 1
214
228
  for m, mslots in enumerate(layer):
215
229
  for k in mslots:
230
+ if abs(k) > Qb:
231
+ continue
216
232
  x = abs(k) * dslot + b
217
- kcoil = (abs(k)-1)//wdg.yd
218
233
  xpoints = []
219
234
  ypoints = []
220
235
  if nl == 2:
@@ -224,6 +239,12 @@ def winding(wdg, ax=0):
224
239
  d = 1 if i == 1 else 0
225
240
  else:
226
241
  d = 0 if k > 0 else 1
242
+ if abs(k) > 1:
243
+ if csl[0][abs(k)-2] == coil_color[m]:
244
+ d = 1
245
+ csl[0][abs(k)-1] = ''
246
+ else:
247
+ d = 0
227
248
 
228
249
  if direction[d] == 'right':
229
250
  # first layer, positive dir or neg. dir and 2-layers:
@@ -2,6 +2,10 @@
2
2
  --
3
3
  -- set rotor bar
4
4
  xb, yb = 0, da2/2 - m.slot_height/2 - m.slot_h1
5
+ x1, y1 = pr2c(da2/2-m.slot_h1-m.slot_height/2, zeroangle)
6
+ x10, y10 = pr2c(da2/2-m.slot_h1-m.slot_height/2, zeroangle + 2*math.pi/Q2)
7
+ xb=(x1+x10)/2
8
+ yb=(y1+y10)/2
5
9
  muer = 1
6
10
  rel = 100
7
11
  cur = {1, 0}
@@ -52,7 +52,7 @@ nc_circle_m(xw2, yw2, x8, y8, 0,0,0)
52
52
  nc_circle_m(x4, y4, xw3, yw3, 0,0,0)
53
53
  nc_circle_m(xw4, yw4, x7, y7, 0,0,0)
54
54
 
55
- x, y = (x4+x7)/2, (y4+y5)/2
55
+ x, y = (x5+x7)/2, (y7+y5)/2
56
56
  create_mesh_se(x, y)
57
57
 
58
58
  def_new_sreg(x, y, 'StZa', 'skyblue')
@@ -67,6 +67,10 @@ m.nu_move_steps = ${model.get('num_move_steps', 49)}
67
67
  m.num_par_wdgs = ${model.get('num_par_wdgs',1)}
68
68
 
69
69
  m.current = ${model.get('current')}*math.sqrt(2.0)/m.num_par_wdgs
70
+ if m.current < 1e-5
71
+ then
72
+ m.current = 1e-5*math.sqrt(2.0)
73
+ end
70
74
  m.angl_i_up = ${model.get('angl_i_up', 0)}
71
75
 
72
76
  m.pocfilename = '${model.get('pocfilename', 'sin.poc')}'
femagtools/windings.py CHANGED
@@ -12,6 +12,12 @@
12
12
  Number of coils per phase: c = Q * l/2/m
13
13
  Number of parallel circuits (coil groups): g
14
14
  Number of turns per phase: w1 = Q * n * l/2/m/g
15
+
16
+ Refs:
17
+ odd number of phases
18
+ doi:10.1007/s00502-021-00873-6
19
+ even number of phases
20
+ doi:10.1049/iet-epa.2020.0553
15
21
  """
16
22
  import numpy as np
17
23
  import femagtools.bch
@@ -131,8 +137,6 @@ def end_wdg_length_hairpins(wire_h, wire_w, wire_th, wire_gap,
131
137
 
132
138
 
133
139
  class Winding(object):
134
- # TODO: raise ValueError "Unbalanced winding" if Q % (m * gcd(Q, p)) != 0
135
-
136
140
  def __init__(self, arg):
137
141
  """create winding either from bch winding section or winding dict()
138
142
 
@@ -199,15 +203,29 @@ class Winding(object):
199
203
  coilwidth = self.yd
200
204
 
201
205
  self.yd = coilwidth
206
+ if self.m % 2: # odd number of phases
207
+ q1, q2, Yk, Qb = q1q2yk(self.Q, self.p, self.m, self.l)
208
+ j = 2 if layers == 1 else 1
209
+ k1 = [(q1 + q2)*i for i in range(self.m)]
210
+ k2 = (q1*(self.m+1) + q2*(self.m-1))//2
211
+ pos = [[(j*Yk*(k + n)) % Qb
212
+ for n in range(q1)] for k in k1]
213
+ neg = [[j*Yk*(k + n + k2) % Qb
214
+ for n in range(q2)] for k in k1]
215
+ else: # even number of phases
216
+ if np.mod(self.Q, 4/self.l*self.m*np.gcd(self.Q, self.p)):
217
+ raise ValueError(
218
+ f"Unbalanced winding: Q={self.Q}, p={self.p}, m={self.m}")
219
+ t = np.gcd(self.Q, self.p)
220
+ Qb = self.Q//t
221
+ seq = np.array([i for j in range(Qb)
222
+ for i in range(Qb) if (j*self.p//t - i) % Qb == 0])
223
+ if self.l == 1:
224
+ seq = seq[::2]
225
+ seq = np.array(seq).reshape((-1, 6))
226
+ pos = seq[::2].T
227
+ neg = seq[1::2].T
202
228
 
203
- q1, q2, Yk, Qb = q1q2yk(self.Q, self.p, self.m, self.l)
204
- j = 2 if layers == 1 else 1
205
- k1 = [(q1 + q2)*i for i in range(self.m)]
206
- k2 = (q1*(self.m+1) + q2*(self.m-1))//2
207
- pos = [[(j*Yk*(k + n)) % Qb
208
- for n in range(q1)] for k in k1]
209
- neg = [[j*Yk*(k + n + k2) % Qb
210
- for n in range(q2)] for k in k1]
211
229
  if self.l > 1:
212
230
  slots = [sorted([(k, 1, 1)
213
231
  for k in p] + [(k, -1, 1)
@@ -495,16 +513,16 @@ class Winding(object):
495
513
  if not is_upper(r, s*taus - (x-taus/2))]
496
514
  for key in self.windings]
497
515
 
498
- z = ([[d*s for s, d in zip(u, ud)] for u, ud in zip(upper, udirs)],
499
- [[d*s for s, d in zip(l, ld)] for l, ld in zip(lower, ldirs)])
516
+ z = ([[int(d*s) for s, d in zip(u, ud)] for u, ud in zip(upper, udirs)],
517
+ [[int(d*s) for s, d in zip(l, ld)] for l, ld in zip(lower, ldirs)])
500
518
  # complete if not basic winding:
501
519
  Qb = self.Q//num_basic_windings(self.Q, self.p, self.l)
502
520
 
503
521
  if not np.asarray(upper).size or not np.asarray(lower).size:
504
522
  layers = 1
505
523
  if layers == 1 and z[1]:
506
- z = ([[d*s for s, d in zip(l, ld)] for l, ld in zip(lower, ldirs)],
507
- [[d*s for s, d in zip(u, ud)] for u, ud in zip(upper, udirs)])
524
+ z = ([[int(d*s) for s, d in zip(l, ld)] for l, ld in zip(lower, ldirs)],
525
+ [[int(d*s) for s, d in zip(u, ud)] for u, ud in zip(upper, udirs)])
508
526
 
509
527
  if max([abs(n) for m in z[0] for n in m]) < Qb:
510
528
  return [[k + [-n+Qb//2 if n < 0 else -(n+Qb//2) for n in k]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: femagtools
3
- Version: 1.8.14
3
+ Version: 1.8.16
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
@@ -1,9 +1,9 @@
1
- femagtools/__init__.py,sha256=gJcP88c10j1_CgFqstAAzR2NxPFwt_-dkoYUz5i2-yk,1601
1
+ femagtools/__init__.py,sha256=yW5kIvW8xbIRiQDkTT8Is4UgEjOhkX7Vqoytu45rvFc,1601
2
2
  femagtools/airgap.py,sha256=hELJXe52yUw82JwZ1tGUXUtRhMG2_WSUBVeGkTZSAM8,1900
3
3
  femagtools/amazon.py,sha256=O1ICuv21XDAJi1qK1Sigs2TdS6hDZP19OzvmE2t76wU,12069
4
4
  femagtools/amela.py,sha256=2q-Xsj6i6nQ3iKheBR1vQ4FulJfF1i-L8w3a3U8GYWo,4362
5
5
  femagtools/asm.py,sha256=CiL0KWaF4P7O6-VwmGLdva_icwmPrPiI-TFQ19XYTKk,7660
6
- femagtools/bch.py,sha256=TC1DKNHuYS9QQNVdBdM1QiMmF6qlT3RnRA4uDMa270c,75623
6
+ femagtools/bch.py,sha256=e6kKyp4iaGb-GPMxwq5LgcyA0GQxteRJDfZsLZVfLyw,75732
7
7
  femagtools/bchxml.py,sha256=KrRjAdrUPZXmiWvonu9HhpG_NvImMBpiXWTL4iSr4kE,3142
8
8
  femagtools/condor.py,sha256=J8z9iBdvrGu3I1eFNoyKV8AXzRoTEPGLSak6cXUQxAM,10766
9
9
  femagtools/conductor.py,sha256=rXO7c7Qh_s7JpgILmLd4IbG64vP6Eh143YF9u25Mdwg,1076
@@ -15,16 +15,16 @@ femagtools/dakotaout.py,sha256=6nn0PXsB40mPKiQLenqAtHy0KXCO7kvqqQ-aD2JhQvw,5573
15
15
  femagtools/docker.py,sha256=XDVmLBB0z4sZZpcrx7Wbm84xl4ksj7aqn5-ZOPxdxm4,7460
16
16
  femagtools/ecloss.py,sha256=3qwfb_9qpWw99asUDcQgdbP51VGXp4MlLQZDhywWHEk,35051
17
17
  femagtools/erg.py,sha256=IXKq76P9qLt_ssNOP78v8Qizk3J2Zg80yaKDSjzwoJE,1224
18
- femagtools/femag.py,sha256=ejagYsOG9CJDcJQvldq3v3NcZ0OdMC5aipZenc-5MI4,44868
18
+ femagtools/femag.py,sha256=rJ_n1Fvu8RcL-6LTH5o-lvV8pP0kpsqmx6RggsiJMhU,45013
19
19
  femagtools/forcedens.py,sha256=7NNv75Vg9vQ_fy8W4kM2rlSO970zaSmeurhPmdAxsOU,8485
20
- femagtools/fsl.py,sha256=AWyc7mIgUL2tjqw_kmK22y-gZXhTzOccyhjJLwCqKcg,37736
20
+ femagtools/fsl.py,sha256=JSalCD21wyYnlwwXeZjUfTca80RnYezrLvDcewlUH-Q,37976
21
21
  femagtools/getset.py,sha256=yJ6Em35DeWK7WNZW0qjjS5s7LUkVh5mbgxF59HHm5FM,3017
22
22
  femagtools/gmsh.py,sha256=IKhNiviIBji4cMxAhxaYXNqBRMNAPSKsBGdnGyxkyQw,3903
23
23
  femagtools/google.py,sha256=ugRyHY1zBjHR4aNfbA7GeF-ZU_NgleuVTZaWpi_XLT4,17144
24
24
  femagtools/grid.py,sha256=s7LfKKLm2H4-cza2kSEANq6vwxq10Su3TJl3kHShHRA,1561
25
25
  femagtools/heat_source_network.py,sha256=dz3nTK084SR2fyy1167wlpBlGrzv54OqCCGKPNWqpsU,16836
26
26
  femagtools/hxy.py,sha256=PkiZ_-CRhtvtpkmLAP8iMtwvzh7CjKGGcAbOhFb4Nls,6275
27
- femagtools/isa7.py,sha256=qtmBx53IIbn4rO2pCTFqn0h1f-REbQ0uEWAJ9T85LgI,67033
27
+ femagtools/isa7.py,sha256=8nQtl9Rcceyay9fSlhWu5zeigCyQ7rFQkPLWrYLU1bw,68345
28
28
  femagtools/jhb.py,sha256=stJxkmzHpfUIBVcFw7jWbV5KN9_EFqzOCgacyhUqWvM,1779
29
29
  femagtools/job.py,sha256=sh4yk8RVEFai7YDBMsVg19p9xEd6_sfyNX5WQSY7HEY,11726
30
30
  femagtools/leakinduc.py,sha256=4IGZaV8S1ZG6L3hgZsCXqMsMNRH4F88l9EsvUjSXDSE,999
@@ -49,7 +49,7 @@ femagtools/ts.py,sha256=yoYjpKrr_0b-tHfsX5azJEBXHUs9PN8P-SMhbjjRhCA,48381
49
49
  femagtools/utils.py,sha256=yZYgAKHsvK7QyY2-ijE3gSzXlE3vfuhD5dx7myyw434,1703
50
50
  femagtools/vbf.py,sha256=9XGfhftmD9carU8ByQ5DwqoR4daq5mJ39eMqruwml0Q,2444
51
51
  femagtools/vtu.py,sha256=Sf83dHIfCKY2km-MIUHKKoj-JKN4PDX7kkPLZXyIYY4,10723
52
- femagtools/windings.py,sha256=p7BkIbi8mMc_CmWqAjOZNKz1-GlQb4kON4rWhvlARf8,27498
52
+ femagtools/windings.py,sha256=eGRoDbi9yruiWHqZysamBLPJefw8IQX3Lq4KpG4oIKo,28216
53
53
  femagtools/zmq.py,sha256=62x5VRk0TMNER0-EZ8E28IdLKzsttlbxy1U_3wocNLc,9618
54
54
  femagtools/dxfsl/__init__.py,sha256=MywcCdpKPKs4qJBJJgeDsikJFJ2P48dbTuNk303f5pM,76
55
55
  femagtools/dxfsl/area.py,sha256=CpTMRBF8_AJmJMkkn-LgRv27U5xJ5Ohhd2ppRvESPNU,69757
@@ -71,12 +71,12 @@ femagtools/dxfsl/shape.py,sha256=uQqbgXIA2_KP2XRdhCfVfGWjcjwzhJ5t9RhiqR9R98c,616
71
71
  femagtools/dxfsl/svgparser.py,sha256=RY2TU9MK6gOaNmI6w6RNqcw7H9YGmK-NUwvdylKBcsE,3763
72
72
  femagtools/dxfsl/symmetry.py,sha256=dXfZVIqT49nbMirY5YVaRPi8kNB8reaiq-eIbhw1Z54,43936
73
73
  femagtools/machine/__init__.py,sha256=xDY9QSUVL2Y17I4fq-nXsb5uMHCIxnCmGVIiL0fZZYE,7447
74
- femagtools/machine/afpm.py,sha256=ZkYk-acfmwV2ebhU8BUE6dKYkDrCR8UKp1plxEdZ4v8,40223
75
- femagtools/machine/effloss.py,sha256=vDFKscFTWuW2ro4DRfNdmehQRhMBvqUG7iTm3YaARi8,16431
76
- femagtools/machine/im.py,sha256=UeN1e0JTwsbaFjGhJFBmhwRDlgckNNf8_A69YmG6ABE,39545
74
+ femagtools/machine/afpm.py,sha256=_Ei1FMuoC1GiI0z90qnyuxNrefkmeRdtDZKm20glzNY,40711
75
+ femagtools/machine/effloss.py,sha256=meQ3bsAORtmn1nMEUfJSiu4YsyfDE5PHc-YNaxnstU4,17093
76
+ femagtools/machine/im.py,sha256=5wYjsEQIiKR62M2M0rA8zmybWQDVjpoazXJPRKyQOvM,40331
77
77
  femagtools/machine/pm.py,sha256=hXG71o2TqTxqy-FRy1WoeSOT-KysOGeZlCCnaLfISuE,70026
78
78
  femagtools/machine/sizing.py,sha256=QO-k-UALmSPFNf8ajJPDnzKtlbkiAhX1DqWCRLr-H9k,32306
79
- femagtools/machine/sm.py,sha256=hQC_guN6qCJPrFWyECNyJyVmu13wzPxTioqXnGT4AtA,39191
79
+ femagtools/machine/sm.py,sha256=qZfCIbm02ELH-RsenzqvjZuqRZ-U7OXQq85iOfZphwo,40671
80
80
  femagtools/machine/utils.py,sha256=HRM9UHY0UwuBWyK2dAfwlPuvMkXYBVqHlmEsUIdSNJk,21694
81
81
  femagtools/moo/__init__.py,sha256=zinmWEOrsEz6DmMX0Dbn4t6_1UR-p4bEGqyR1wUQk_Q,175
82
82
  femagtools/moo/algorithm.py,sha256=e-Cgp2rp_hG9DXqWqluzQGNIWvCfthUgLD8O-aVPofA,5763
@@ -87,15 +87,15 @@ femagtools/moo/test/PopulationTest.py,sha256=lG9NeWo0xrslfQRa4tgy1Nj23VJMFIlg_vQ
87
87
  femagtools/moo/test/ProblemTest.py,sha256=r5XEfY4LPscDb35TxxPd0lbP3nUmL6_G6vrRo1I3RSg,505
88
88
  femagtools/plot/__init__.py,sha256=LFrHy_9L6FxJqhYND2z1534s3ebPXkfXVagFeNA1wWk,978
89
89
  femagtools/plot/bch.py,sha256=EhW_YRgMZU4K1Az_XAK1XGG0JAtrDwmwZ6SHdvPi4-c,34085
90
- femagtools/plot/char.py,sha256=xv4cNOTorK-fy7eUFhmyR-013TFI2A2999xXKgL2AnA,12469
90
+ femagtools/plot/char.py,sha256=8eA1sEt-xKAqOZNlB6tx33DNXVsO3N7ius5KcV9lSv4,12771
91
91
  femagtools/plot/fieldlines.py,sha256=_7ykKhnQLeS4fz34pnzovH1gIhcUSKJ3gl1GUgWYix8,1137
92
92
  femagtools/plot/fluxdens.py,sha256=NlexRJ3f_8CgKoWrV82ZIsAXPrLhwj98uOe8_fUks7A,1082
93
93
  femagtools/plot/forcedens.py,sha256=Vloi9czy7qbGXI-Vm7Cow6IfHTsFhCLI1YWduFOR55c,4075
94
94
  femagtools/plot/machine.py,sha256=fVLOZTc19Ru8eXLdtoTeIYsHRWhGLkn_YVZ6qO6KgrE,2654
95
95
  femagtools/plot/mcv.py,sha256=ijZg6KPwZC7sDxEzGEUfVWvDoSEfgcaH-hzQMt7E90I,3671
96
- femagtools/plot/nc.py,sha256=E7_7WNG3MNrV4QPJJqng1nfuXf3ZbjAGeonthqQlMss,11349
96
+ femagtools/plot/nc.py,sha256=OWmO8-WF303z5-zeBGkNJ8N09RJvH7sEYgOuK3LJaR8,11630
97
97
  femagtools/plot/phasor.py,sha256=5QG1GkXKVksc8P6Q4thKADf6W1l8rDKeArIHFYvbXlw,4858
98
- femagtools/plot/wdg.py,sha256=Orw2XGThHpOuJ_raSRnQTzj5tOmwllNWweByoOXbA7I,9820
98
+ femagtools/plot/wdg.py,sha256=uTEtpW_xCXueGnkWx8fTQHruBiayw62AVTXkc9vz9iM,10536
99
99
  femagtools/svgfsl/converter.py,sha256=5q4LognshXNTpUWLnU5rtgCfAwZnEuPzqsgyeRYC-VM,3019
100
100
  femagtools/templates/FE-losses.mako,sha256=cfDlO11vWovz2muPLg9X2rgeHD9Ihaz8PRiz63MRr88,819
101
101
  femagtools/templates/afm_rotor.mako,sha256=4yoEA4fOq9FRcwxOMRw1oX4Bs_jcrtyHOY6kHPYJ5MY,3175
@@ -113,7 +113,7 @@ femagtools/templates/conduct-data.mako,sha256=quT9S1cq2C2GyeoUe-erxV6w20KvRPuJVJ
113
113
  femagtools/templates/connect_models.mako,sha256=8j1hzBMeoDJ7-GL5BH-S5p53Bu5jtqqsC2_w6MSwWnI,663
114
114
  femagtools/templates/cu_losses.mako,sha256=EeNwINYuwBuhbo9LH3STdQOTxOyyWw_BANgh_BSV9TE,1339
115
115
  femagtools/templates/displ_stator_rotor.mako,sha256=dsf9qW0i79aWAbOxaHwWfiq-Tn6WCDx46PQyEvL3SMw,830
116
- femagtools/templates/ec-rotorbar.mako,sha256=RbA1TVNczEEddTNjvGLPxILExxp4rIgoxXe1YT6a4Is,1672
116
+ femagtools/templates/ec-rotorbar.mako,sha256=fbZ2QTw3YbvWgZJRUEHCnRG_EirdFqCFBiFxlgqQRD4,1833
117
117
  femagtools/templates/fe-contr.mako,sha256=Gj4EFpAk_SVW_SIeW5eRRJAsYXTTpl-djuyb47n3Dj8,1898
118
118
  femagtools/templates/fieldcalc.mako,sha256=bEtff9HeD6hTpB9t3COt40V1oGeT0a_6ouWTQlKIGX8,749
119
119
  femagtools/templates/gen_hairpin_winding.mako,sha256=O3up0yjj3BDqFgpIY28fILKt7NX9NbgXTbd0sb3MM6A,5340
@@ -166,13 +166,13 @@ femagtools/templates/stator2.mako,sha256=7Ae9sfaX7H4ummL6-g8iG42ArUvl6J809TW2tOd
166
166
  femagtools/templates/stator3Linear.mako,sha256=pNe3C1wT0W2C0qePo3sEyebW1z_dpTuJzg0r5kf3JQY,760
167
167
  femagtools/templates/stator4.mako,sha256=Jq8pfIuOmmpyGOL1z2aQZfbwMS5-Zyn6OGJ51LCBVKs,1179
168
168
  femagtools/templates/statorBG.mako,sha256=fh0cVOZVWyLojlGxWJoFz2pvdL6Yxy4xzhY-Joc2xeg,893
169
- femagtools/templates/statorRing.mako,sha256=sDgDmk71EoE8d4e9cmyqKqRldfC8uKMmpHEjXJGIt_k,2071
169
+ femagtools/templates/statorRing.mako,sha256=_X8t9oAD_6SZ_MlLc450SkN4C6pH4dG5LS09D8bv9SE,2071
170
170
  femagtools/templates/statorRotor3.mako,sha256=6ycHlkSnk-TKFdoxiOqjpr6Pk0l634w3_O94vvRP4BI,4357
171
171
  femagtools/templates/stator_msh.mako,sha256=Neze1ielMCk7TrARyhOra91fFQVT8Phsgk2Omt_aMG8,1799
172
172
  femagtools/templates/therm-dynamic.mako,sha256=pEz7jrUpopK1-RqgulNnrkSaCZDjfLelsVo6cBqmpac,3142
173
173
  femagtools/templates/therm_static.mako,sha256=ulevp4AP-kZ1_qdScPMaX9tLqvvP0t9lFflWTXgUxaE,1310
174
- femagtools/templates/torq_calc.mako,sha256=et6O9ZEkPMOYcaJVpYtH2u3aoU0iyhRCPkfN4ZLdjxA,2353
175
- femagtools-1.8.14.dist-info/licenses/LICENSE,sha256=NaQe4uvkszQPJmiRPHecfk-Ab9VSRXo8xQLGNVHTeFo,1362
174
+ femagtools/templates/torq_calc.mako,sha256=PH2IXg9ysi0w8N_8YB0IsE3rRj2VE2AYkGortQxFGfQ,2424
175
+ femagtools-1.8.16.dist-info/licenses/LICENSE,sha256=NaQe4uvkszQPJmiRPHecfk-Ab9VSRXo8xQLGNVHTeFo,1362
176
176
  tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
177
177
  tests/test_afpm.py,sha256=ge5CXnVQ7E5gVViTI9hQOC0hHetBci18pY9prbUCAqU,16849
178
178
  tests/test_airgap_induction.py,sha256=cmpy1og59oWEyCO4oF_zDuc1DUwCbdeebNL1ujpZza4,1065
@@ -182,26 +182,26 @@ tests/test_bchreader.py,sha256=YPU00nl2MXQiMr1i-W4UOgUvKheeW5tqv_OpTBBOK0g,16835
182
182
  tests/test_conductor.py,sha256=T7bmuSdI2Fowwm2Ht-8D0Qnfs1_lx1aoi9RhC2p5nYU,332
183
183
  tests/test_convert.py,sha256=oseuhm3Iw-9b4WzBjA_Og2lgXPqKYicLUnfadq5Yick,6497
184
184
  tests/test_dxfsl.py,sha256=DBAjtwNAwcB7VYZBjul7xf4ovu14n3Z0fxyreVzAW4A,383
185
- tests/test_effloss.py,sha256=-kJJNgS5c6saHXjNuhAe5GdWfr9mEYpPo8fE8OtjsNA,1142
185
+ tests/test_effloss.py,sha256=pBGuzUeyDZ5jUp92jvVSVPOa4r_5bBYZ1GZH5HRdV3o,1158
186
186
  tests/test_erg.py,sha256=kRVzpXa6JDdbxTss18HUWKny9Dx8IMx9uGTrbQCnHwg,523
187
187
  tests/test_femag.py,sha256=l7-av3eitLm7bwTuunEmVeTspi82ifPrlz7f1boGdVI,1934
188
188
  tests/test_forcedens.py,sha256=Yzl3SAmJNkZN9dA3aLxRvwY8fKsw077Fl0iJm6zJ5Sk,536
189
- tests/test_fsl.py,sha256=oe5dHxR0G3sfGvsRtO6fEIn0R3oQFugsSkGzhyFPQR4,16624
189
+ tests/test_fsl.py,sha256=mSk7de5IenY_iWJDgxdKRqZVza4P3gw8s1Hayl7kIYw,16624
190
190
  tests/test_heat_source_network.py,sha256=TC-Gl4iy9jnMGfsY_24XjwlP-SDxP345JKVT8xRwsFo,690
191
191
  tests/test_hxy.py,sha256=pVb6ZfDhBy5-DXa3gh7RQmLFG8p5cSYB8gdGLC8kjAk,640
192
- tests/test_im.py,sha256=55wfCoA8_PuogI_RsC3AjUQCpR84T-HddtHuU1NxfPc,662
192
+ tests/test_im.py,sha256=RU2SJKvXsavQSth2sHjeOs-eXNegz9GQXTUCcow8H3s,1888
193
193
  tests/test_isa7.py,sha256=GJhRj2nncrUpNTIlM4jvG4kKZS7cK19hhQg9KbM3b5Q,3001
194
194
  tests/test_jhb.py,sha256=aDzwr2ZaXlizrPnlLlcI_IT3OpSxuKu-FzBBkIALEDg,824
195
195
  tests/test_job.py,sha256=1tCTPqd2LUeeVNuzC07lsPz4ffr0WAVX_BykyXQ2mZY,981
196
196
  tests/test_losscoeffs.py,sha256=3EKmDFRuvn88z_8r0HxKFdB0lNXNnhEgaFshL8BkDjE,2012
197
- tests/test_machine.py,sha256=Woha6nfKaYQCxxoG57sUztpnpU6K9imXwn9B_KMhanw,12906
197
+ tests/test_machine.py,sha256=BBaeypcFCpGZfJM52_rUIrA3uu17n4_IT1Y05W_caSA,12960
198
198
  tests/test_magncurv.py,sha256=wPf1dNACZ1BkqKHSqJxiNi6Dq8JP3QCRBY4ql_0YCyU,2608
199
199
  tests/test_magnet.py,sha256=BUHG_8SEi4d8j6yV9BSzcpYc2-UVMRFv50P_jgTTXoQ,276
200
200
  tests/test_mcv.py,sha256=Vv51WU3WU0AkgcSpyujMdJ2KvSdLNsks5HGtY0pWMOY,4749
201
201
  tests/test_mcvreader.py,sha256=3cgq22b_iaWLrs4WWOUNHqJREnv0YoFivNpAb4teEJs,2118
202
202
  tests/test_me.py,sha256=En00OrOhZclBO4u74q5Os0FgVP4TGFLzz99LF0QHXHA,196
203
203
  tests/test_model.py,sha256=kYjjFgZPIex3foX3skiOdD5MCcmA2JP7oDDuE9txv_U,2698
204
- tests/test_nc.py,sha256=Qhd8SppnWULcEiGphhhn4K_8PfhV7Wh17NAC63R_-N0,4630
204
+ tests/test_nc.py,sha256=lx46Yeco1nuwTtBe4XmdR92tkD9FLmL1VcJgMg-rrLU,5198
205
205
  tests/test_parident.py,sha256=zwj-f-Q_s5dBr_fEvzd5iZqNVIcLwkoi_FF2_FNTiaw,1393
206
206
  tests/test_parstudy.py,sha256=wk7WfYQrx5dtv6MnmWCfNAEInvRKsbVXYEUIIR9zLbQ,3200
207
207
  tests/test_pocfile.py,sha256=eiMLBRQxDnHIGiqku6EXcQ3fb7wGIxhXmb20iyLlPRU,5816
@@ -211,7 +211,7 @@ tests/test_tksreader.py,sha256=8QtPAzxPJbkpxd1Nw2I7ggaTaKaL4WY55JJBHkZAzus,766
211
211
  tests/test_ts.py,sha256=tR2x5cKU9gw2fUprzaPgPbCvmDOHDO36JUPCCoTlY7Y,1833
212
212
  tests/test_vbfreader.py,sha256=-6oAhLJDb7K3Ui5O1mtHvbskawEfgyIH-Of5n-8u-fc,832
213
213
  tests/test_vtu.py,sha256=pGpHuAcaCk5zDYTBBp_akOEenZOpq-IzGl_kaMtodyA,1469
214
- tests/test_windings.py,sha256=rZjAudsSCHedbo5BWt1ZVaU49ktxjOim1r7BzJmSdUo,5841
214
+ tests/test_windings.py,sha256=WKFabGC6-TpCnxXL9U91J84INK_ntkMMU1FZRuE7m6k,6142
215
215
  tests/engines/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
216
216
  tests/engines/test_amazon.py,sha256=4uy36NIo0epi3CgjUm8vl4snLpr4NRvUoWi6Zew_zcE,2014
217
217
  tests/engines/test_config.py,sha256=_I1Z5RuubgnOGQeZHjAsCsovt0WEMH0o4ILz032l_Bc,663
@@ -222,8 +222,8 @@ tests/moo/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
222
222
  tests/moo/test_algorithm.py,sha256=Em8sFm2vzPmuIzRrBBnUQLU_TYuJHSf-kEeozw0XeX4,2563
223
223
  tests/moo/test_population.py,sha256=FvX9LRCxQx0_E2GxHQ5vKwOYFBQiNbT6Lmv5GmNWjTQ,5471
224
224
  tests/moo/test_problem.py,sha256=ALeP4u7g-dFhfwWL8vxivdrrYzVKPjHMCAXzzgyNZbs,467
225
- femagtools-1.8.14.dist-info/METADATA,sha256=BrabUwTwkjyUIeeY3Ln1RIyfy1FQefxu8EgDckCsobA,6213
226
- femagtools-1.8.14.dist-info/WHEEL,sha256=DnLRTWE75wApRYVsjgc6wsVswC54sMSJhAEd4xhDpBk,91
227
- femagtools-1.8.14.dist-info/entry_points.txt,sha256=jrvOkZPiN44u1sASeu271VRaVIv5V-uRpN0_N5U_R8c,248
228
- femagtools-1.8.14.dist-info/top_level.txt,sha256=Ri4YWtU8MZTzNje9IKyXhTakNbsrCynuWdon4Yq94Dc,17
229
- femagtools-1.8.14.dist-info/RECORD,,
225
+ femagtools-1.8.16.dist-info/METADATA,sha256=H9y1DOCVUWBJhZgyHDJa1Vqt9r7xHZg9rZUiWXUxEoQ,6213
226
+ femagtools-1.8.16.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
227
+ femagtools-1.8.16.dist-info/entry_points.txt,sha256=jrvOkZPiN44u1sASeu271VRaVIv5V-uRpN0_N5U_R8c,248
228
+ femagtools-1.8.16.dist-info/top_level.txt,sha256=Ri4YWtU8MZTzNje9IKyXhTakNbsrCynuWdon4Yq94Dc,17
229
+ femagtools-1.8.16.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.4.0)
2
+ Generator: setuptools (80.9.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
tests/test_effloss.py CHANGED
@@ -14,7 +14,7 @@ def impars():
14
14
  'im': [2.043764851047857, 4.087529702095714, 6.1312945531435705,
15
15
  8.175059404191428, 10.218824255239285],
16
16
  'psi': [0.27117452078113785, 0.5286659550273167, 0.7135568973434478,
17
- 0.8133415467307101, 0.8671946085010127]}
17
+ 0.8133415467307101, 0.8671946085010127], 'tfric': 0.099}
18
18
 
19
19
 
20
20
  def test_imeffloss(impars):
tests/test_fsl.py CHANGED
@@ -327,7 +327,7 @@ class FslBuilderTest(unittest.TestCase):
327
327
 
328
328
  feapars['calculationMode'] = "torq_calc"
329
329
  fsl = self.builder.create_analysis(feapars)
330
- self.assertEqual(len(fsl), 28)
330
+ self.assertEqual(len(fsl), 32)
331
331
 
332
332
  def test_run_existing_model(self):
333
333
  model = femagtools.MachineModel('data/magnsec')
tests/test_im.py CHANGED
@@ -3,6 +3,7 @@ import pathlib
3
3
  import pytest
4
4
  import numpy as np
5
5
 
6
+ from femagtools.machine.im import InductionMachine
6
7
 
7
8
  @pytest.fixture
8
9
  def im():
@@ -21,3 +22,28 @@ def test_im(im):
21
22
  s = 0.01
22
23
  torque = im.torqueu(2*np.pi*f1, u1, 2*np.pi*(1-s)*f1/im.p)
23
24
  assert pytest.approx(torque, rel=0.01) == 17.77
25
+
26
+ def test_characteristics():
27
+ m = {'r1': 0.675074272807, 'ls': 0.0, 'le': 0.0, 'wdgcon': 1.0, 'bar_temp': 80.0,
28
+ 'im': [0.815370706376, 3.15956148721, 5.50375226804, 7.84794304887, 10.1921338297],
29
+ 'psi': [0.110531890489, 0.42241005873, 0.64470403922, 0.742820604784, 0.791593101916],
30
+ 'lsigma1': 0.00282975049013, 'lsigma2': 0.00170976658221, 'r2': 0.526553117684,
31
+ 'u1ref': 230.940107676, 'f1ref': 49.9998282765, 'rotor_mass': 10.0742734696, 'kfric_b': 1.0,
32
+ 'zeta2': 0.983497740554, 'pl2v': 0.801009432234, 'psiref': 0.717940875943, 'wref': 314.158186388,
33
+ 'fec': 61.5, 'fee': 0.0, 'fexp': 7.0, 'kth1': 0.0039, 'kth2': 0.0039, 'p': 4, 'm': 3, 'u_1': 165.0}
34
+
35
+ op = {'n': [0.0, 16.0, 41.0],
36
+ 'T': [50.0, 47.5, 42.5]}
37
+
38
+ tmech = True
39
+ im = InductionMachine(m)
40
+ u1 = m['u_1']
41
+ m.pop('u_1')
42
+
43
+ r = im.characteristics(op['T'], op['n'], u1,with_tmech=tmech)
44
+
45
+ expected = {'losses': [237.01, 237.12, 236.46],
46
+ 'eta': [0, 0.76, 0.88]}
47
+
48
+ assert pytest.approx(expected['losses'], rel=1e-1) == r['losses']
49
+ assert pytest.approx(expected['eta'], rel=1e-1) == r['eta']
tests/test_machine.py CHANGED
@@ -169,7 +169,7 @@ def test_char_ldd_fieldweakening():
169
169
  assert r['beta'][0] == pytest.approx(-30.0, rel=1e-1)
170
170
  assert r['cosphi'][0] == pytest.approx(0.729, rel=1e-1)
171
171
 
172
-
172
+ @pytest.mark.skip(reason="fixit: returns currently 0")
173
173
  def test_i1beta_char():
174
174
  m = dict(
175
175
  p=4,
tests/test_nc.py CHANGED
@@ -1,3 +1,4 @@
1
+ import numpy as np
1
2
  import pytest
2
3
  from femagtools import nc
3
4
  from femagtools import isa7
@@ -165,3 +166,19 @@ def test_windings(disp_stat):
165
166
  def test_magnet_super_elements(disp_stat):
166
167
  sekeys = [se.key for se in disp_stat.magnet_super_elements()]
167
168
  assert sekeys == [98, 101, 74, 77, 80, 83, 86, 89, 92, 95]
169
+
170
+
171
+ def test_punchdist(pm):
172
+ expected_shape = ((1008, 2), (520, 2))
173
+ for i, name in enumerate(pm.get_iron_subregions()):
174
+ sr = pm.get_subregion(name)
175
+ bnxy, bkeys = sr.nonper_border_nodes()
176
+ assert expected_shape[i] == np.shape(bnxy)
177
+ assert expected_shape[i][0] == 2*len(bkeys)
178
+
179
+ bnxy = pm.lamination_border()
180
+ assert (764, 2) == np.shape(bnxy)
181
+ elam, pdist = pm.punchdist()
182
+ assert 6714 == len(elam)
183
+ assert (6714, ) == np.shape(pdist)
184
+ assert pytest.approx(0.0041973, abs(1e-3)) == np.max(pdist)
tests/test_windings.py CHANGED
@@ -163,3 +163,14 @@ def test_zoneplan():
163
163
  w = femagtools.windings.Winding(
164
164
  {'Q': 60, 'p': 32, 'm': 3, 'l': 1})
165
165
  assert [1, -2, 3, -4, 5, -6, -17, 18, -19, 20] == w.zoneplan()[0][0]
166
+
167
+ def test_zoneplan_6phase():
168
+ w = femagtools.windings.Winding(
169
+ {'Q': 24, 'p': 11, 'm': 6, 'l': 1})
170
+ assert [
171
+ [1, -2, -13, 14],
172
+ [-11, 12, 23, -24],
173
+ [-9, 10, 21, -22],
174
+ [-7, 8, 19, -20],
175
+ [-5, 6, 17, -18],
176
+ [-3, 4, 15, -16]] == w.zoneplan()[0]