femagtools 1.8.17__py3-none-any.whl → 1.8.18__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/femag.py CHANGED
@@ -79,6 +79,7 @@ def set_magnet_properties(model, simulation, magnets):
79
79
  magn_temp = simulation.magn_temp
80
80
  if 'material' not in model.magnet:
81
81
  return
82
+
82
83
  try:
83
84
  material = model.magnet['material']
84
85
  magnetMat = magnets.find(material)
@@ -95,19 +96,24 @@ def set_magnet_properties(model, simulation, magnets):
95
96
  tempcoefmuer = (tempcoefbr-tempcoefhc)/(1+tempcoefhc*(magn_temp-20))
96
97
  if 'temcoefmuer' in magnetMat:
97
98
  tempcoefmuer = magnetMat['temcoefmuer']
98
- hcj = magnetMat.get('HcJ', 0)
99
- if hcj:
100
- model.hc_min = -hcj * (1+tempcoefhc*(magn_temp-20))
99
+ if not hasattr(model, 'hc_min'):
100
+ for k in 'Hk', 'HcJ':
101
+ if k in magnetMat:
102
+ hcmin = magnetMat.get(k)
103
+ model.hc_min = hcmin * (1+tempcoefhc*(magn_temp-20))
104
+ break
105
+ if hasattr(model, 'hc_min'):
106
+ logger.info("hc_min %f", model.hc_min)
101
107
  model.magnet['temp_prop']['relperm'] = \
102
108
  (1+tempcoefmuer*(magn_temp-20))*relperm
103
109
  if tempcoefbr:
104
110
  model.magnet['temp_prop']['temcoefbr'] = tempcoefbr
105
111
  if tempcoefhc:
106
112
  model.magnet['temp_prop']['temcoefhc'] = tempcoefhc
107
-
108
113
  except AttributeError:
109
114
  pass
110
115
 
116
+
111
117
  class BaseFemag(object):
112
118
  def __init__(self, workdir, cmd, magnetizingCurves, magnets, condMat,
113
119
  templatedirs=[]):
@@ -415,7 +421,8 @@ class BaseFemag(object):
415
421
  except FileNotFoundError:
416
422
  pass
417
423
 
418
- return list(pathlib.Path(self.workdir).glob('*.PROT'))[0].stem
424
+ return sorted(pathlib.Path(self.workdir).glob('*.PROT'),
425
+ key=lambda x: x.stat().st_mtime, reverse=True)[0].stem
419
426
 
420
427
  def readResult(self, machine, simulation, bch=None):
421
428
  if simulation:
@@ -460,14 +467,6 @@ class BaseFemag(object):
460
467
 
461
468
  if not bch:
462
469
  bch = self.read_bch(self.modelname)
463
- if simulation['calculationMode'] == 'pm_sym_fast' or \
464
- simulation['calculationMode'] == 'torq_calc':
465
- if simulation.get('shortCircuit', False):
466
- from .shortcircuit import shortcircuit
467
- set_magnet_properties(self.model, simulation, self.magnets)
468
- bch.scData = shortcircuit(self, machine, bch, simulation)
469
- #bch.torque += bchsc.torque
470
- #bch.demag += bchsc.demag
471
470
 
472
471
  if 'airgap_induc' in simulation:
473
472
  try:
@@ -477,6 +476,19 @@ class BaseFemag(object):
477
476
  bch.airgap = ag.read(os.path.join(self.workdir, 'bag.dat'),
478
477
  pmod=pmod)
479
478
 
479
+ if simulation['calculationMode'] == 'pm_sym_fast' or \
480
+ simulation['calculationMode'] == 'torq_calc':
481
+ if simulation.get('shortCircuit', False):
482
+ from .shortcircuit import shortcircuit
483
+ set_magnet_properties(self.model, simulation, self.magnets)
484
+ bch.scData = shortcircuit(self,
485
+ {'name': self.model.name,
486
+ 'poles': self.model.poles,
487
+ 'hc_min': self.model.get('hc_min', 0)},
488
+ bch, simulation)
489
+ #bch.torque += bchsc.torque
490
+ #bch.demag += bchsc.demag
491
+
480
492
  if simulation.get('magnet_loss', False):
481
493
  logger.info('Evaluating magnet losses...')
482
494
  ops = range(len(bch.torque))
@@ -490,7 +502,7 @@ class BaseFemag(object):
490
502
 
491
503
  if len(ops) != len(bch.losses):
492
504
  magn_losses.insert(0, magn_losses[0])
493
-
505
+
494
506
  magn_losses = [float(i) for i in magn_losses]
495
507
  try:
496
508
  for i in range(len(bch.losses)):
@@ -600,10 +612,9 @@ class Femag(BaseFemag):
600
612
  os.remove(f)
601
613
 
602
614
  def __call__(self, machine, simulation={},
603
- options=['-b'], fsl_args=[]):
615
+ options=['-b'], fsl_args=[], fslfile='femag.fsl'):
604
616
  """setup fsl file, run calculation and return
605
617
  BCH, ASM, TS or LOS results if any."""
606
- fslfile = 'femag.fsl'
607
618
  with open(os.path.join(self.workdir, fslfile), 'w') as f:
608
619
  f.write('\n'.join(self.create_fsl(machine,
609
620
  simulation)))
@@ -51,6 +51,8 @@ def create_from_eecpars(temp, eecpars, lfe=1, wdg=1):
51
51
  smpars = copy.deepcopy(eecpars)
52
52
  smpars['tcu1'] = temp[0]
53
53
  smpars['tcu2'] = temp[1]
54
+ # external inductances
55
+ opts["ls"] = eecpars.get('ls1', 0)*rwdg**2
54
56
  if 'ldq' in smpars:
55
57
  machine = SynchronousMachineLdq(smpars, lfe=rlfe, wdg=rwdg, **opts)
56
58
  else:
@@ -252,6 +252,8 @@ def efficiency_losses_map(eecpars, u1, T, temp, n, npoints=(60, 40),
252
252
  rb['n'] = None
253
253
  rb['T'] = None
254
254
  if 'n' not in rb:
255
+ if kwargs.get('i1max', 0):
256
+ kwargs['i1max'] = -kwargs['i1max']
255
257
  rb = m.characteristics(-T, max(r['n']), u1, nsamples=nsamples,
256
258
  with_mtpv=with_mtpv, with_mtpa=with_mtpa,
257
259
  with_pmconst=with_pmconst, with_tmech=with_tmech,
@@ -267,13 +269,17 @@ def efficiency_losses_map(eecpars, u1, T, temp, n, npoints=(60, 40),
267
269
  if isinstance(m, (SynchronousMachineLdq, SynchronousMachinePsidq)):
268
270
  iq, id, iex = m.iqd_torque(T[-1])
269
271
  i1max = betai1(iq, id)[1]
272
+ if kwargs.get("i1max", 0):
273
+ i1max = kwargs["i1max"]
270
274
  w1type, tmax = m.w1_imax_umax(i1max, u1)
271
275
  pmax = tmax*w1type/m.p
272
276
  else:
273
277
  iq, id = m.iqd_torque(T[-1])
274
- w1type, tmax = m.w1_imax_umax(betai1(iq, id)[1], u1)
278
+ i1max = betai1(iq, id)[1]
279
+ if kwargs.get("i1max", 0):
280
+ i1max = kwargs["i1max"]
281
+ w1type, tmax = m.w1_imax_umax(i1max, u1)
275
282
 
276
- i1max = betai1(iq, id)[1]
277
283
  logger.info("%s %s", n, T)
278
284
  for nx in n:
279
285
  w1 = 2*np.pi*nx*m.p
@@ -431,7 +437,7 @@ def efficiency_losses_map(eecpars, u1, T, temp, n, npoints=(60, 40),
431
437
  e = pm / p1
432
438
  else:
433
439
  e = p1 / pm
434
- eta.append(e)
440
+ eta.append(float(e))
435
441
 
436
442
  return dict(
437
443
  iq=iqd[0].tolist(),
@@ -450,4 +456,4 @@ def efficiency_losses_map(eecpars, u1, T, temp, n, npoints=(60, 40),
450
456
  plfric=plfric.tolist(),
451
457
  losses=ploss.tolist(),
452
458
  plcu1_dc=plcu1_dc,
453
- plcu1_ac=plcu1_ac)
459
+ plcu1_ac=plcu1_ac)
femagtools/machine/pm.py CHANGED
@@ -182,6 +182,8 @@ class PmRelMachine(object):
182
182
  return (0, 0)
183
183
  if np.isscalar(iqd0):
184
184
  i0 = self.io
185
+ if torque<0:
186
+ i0[0] = -i0[0]
185
187
  else:
186
188
  i0 = iqd0
187
189
  if with_mtpa:
@@ -193,10 +195,14 @@ class PmRelMachine(object):
193
195
  if res.success:
194
196
  #raise ValueError(f'Torque {torque}, io {i0}: {res.message}')
195
197
  return res.x
198
+ # should not happen
196
199
  def func(i1):
197
200
  return torque - self.mtpa(i1)[2]
201
+ # with warnings.catch_warnings():
202
+ # warnings.simplefilter("error")
198
203
  i1 = so.fsolve(func, res.x[0])[0]
199
204
  return self.mtpa(i1)[:2]
205
+
200
206
  def func(iq):
201
207
  return torque - self.torque_iqd(iq, 0)
202
208
  return so.fsolve(func, 0)[0]
@@ -220,7 +226,7 @@ class PmRelMachine(object):
220
226
  else:
221
227
  i0 = (iq0, 0)
222
228
  logger.debug("initial guess i0 %f -> %s tx %f torque %f",
223
- self.io[0], i0, tx, torque)
229
+ self.io[0], i0, tx, torque)
224
230
  else:
225
231
  i0 = iqd0
226
232
 
@@ -237,7 +243,7 @@ class PmRelMachine(object):
237
243
  # make new initial guess:
238
244
  tx = self.tmech_iqd(*i0, n)
239
245
  logger.debug("k %d new guess i0 %s tx %f torque %f",
240
- k, i0, tx, torque)
246
+ k, i0, tx, torque)
241
247
  i0=(min(0.9*self.i1range[1]/np.sqrt(2), torque/tx*i0[0]), 0)
242
248
  k += 1
243
249
  raise ValueError(
@@ -247,39 +253,6 @@ class PmRelMachine(object):
247
253
  iq = so.fsolve(tqiq, (i0[0],))[0]
248
254
  return iq, 0, self.tmech_iqd(iq, 0, n)
249
255
 
250
- def iqd_tmech0(self, torque, n, iqd0=0, with_mtpa=True):
251
- """return minimum d-q-current for shaft torque"""
252
- if np.abs(torque) < 1e-2:
253
- return (0, 0)
254
- if np.isscalar(iqd0):
255
- i0 = self.io
256
- else:
257
- i0 = iqd0
258
-
259
- if with_mtpa:
260
- res = so.minimize(
261
- lambda iqd: la.norm(iqd), i0, method='SLSQP',
262
- constraints=({'type': 'eq',
263
- 'fun': lambda iqd:
264
- self.tmech_iqd(*iqd, n) - torque}))
265
- if res.success:
266
- return res.x
267
-
268
- #logger.warning("n: %s, torque %s: %s %s",
269
- # 60*n, torque, res.message, i0)
270
- # try a different approach:
271
- #raise ValueError(
272
- # f'Torque {torque:.1f} speed {60*n:.1f} {res.message}')
273
- def func(i1):
274
- return torque - self.mtpa_tmech(i1, n)[2]
275
- i1 = so.fsolve(func, res.x[0])[0]
276
- return self.mtpa_tmech(i1, n)[:2]
277
-
278
- def tqiq(iq):
279
- return torque - self.tmech_iqd(float(iq), 0, n)
280
- iq = so.fsolve(tqiq, (i0[0],))[0]
281
- return iq, 0, self.tmech_iqd(iq, 0, n)
282
-
283
256
  def tloss_iqd(self, iq, id, n):
284
257
  """return loss torque of d-q current, iron loss correction factor
285
258
  and friction windage losses"""
@@ -350,12 +323,12 @@ class PmRelMachine(object):
350
323
  sign = -1 if i1max > 0 else 1
351
324
  res = so.minimize(
352
325
  lambda n: sign*self.tmech_iqd(iq, id, n),
353
- n0,
354
- constraints={
355
- 'type': 'eq',
356
- 'fun': lambda n:
357
- np.sqrt(2)*u1max - np.linalg.norm(
358
- self.uqd(2*np.pi*n*self.p, iq, id))})
326
+ n0,
327
+ constraints={
328
+ 'type': 'eq',
329
+ 'fun': lambda n:
330
+ np.sqrt(2)*u1max - np.linalg.norm(
331
+ self.uqd(2*np.pi*n*self.p, iq, id))})
359
332
  return 2*np.pi*res.x[0]*self.p, self.tmech_iqd(iq, id, res.x[0])
360
333
 
361
334
  return so.fsolve(lambda x: np.linalg.norm(
@@ -453,22 +426,26 @@ class PmRelMachine(object):
453
426
  i1 = self.i1_tmech(torque, 0, n)
454
427
  i0 = iqd(0, i1)
455
428
 
429
+ logger.debug("i0 %s", i0)
456
430
  if np.linalg.norm(self.uqd(w1, *i0))/np.sqrt(2) > u1max:
457
431
  beta, i1 = betai1(*i0)
458
432
  with warnings.catch_warnings():
459
433
  warnings.simplefilter("ignore")
460
- i0 = iqd(so.fsolve(lambda b: u1max - np.linalg.norm(
461
- self.uqd(w1, *iqd(b, i1)))/np.sqrt(2),
462
- beta)[0], i1)
434
+ bx, _, ier, msg = so.fsolve(lambda b: u1max - np.linalg.norm(
435
+ self.uqd(w1, *iqd(b, i1)))/np.sqrt(2), beta,
436
+ full_output=True)
437
+ i0 = iqd(bx[0], i1)
438
+ logger.debug("i0 %s ier %d %s", i0, ier, msg)
463
439
 
464
- res = so.minimize(lambda iqd: np.linalg.norm(iqd), i0, method='SLSQP',
465
- constraints=(
466
- {'type': 'eq',
467
- 'fun': lambda iqd:
468
- self.tmech_iqd(*iqd, n) - torque},
469
- {'type': 'ineq',
470
- 'fun': lambda iqd:
471
- np.sqrt(2)*u1max - la.norm(self.uqd(w1, *iqd))}))
440
+ res = so.minimize(
441
+ lambda iqd: np.linalg.norm(iqd), i0, method='SLSQP',
442
+ constraints=(
443
+ {'type': 'eq',
444
+ 'fun': lambda iqd:
445
+ self.tmech_iqd(*iqd, n) - torque},
446
+ {'type': 'ineq',
447
+ 'fun': lambda iqd:
448
+ np.sqrt(2)*u1max - la.norm(self.uqd(w1, *iqd))}))
472
449
  iq, id = res.x
473
450
  else:
474
451
  iq, id = i0
@@ -587,18 +564,19 @@ class PmRelMachine(object):
587
564
  log((iq, id, tq))
588
565
  return iq, id, tq
589
566
 
590
- def iqd_imax_umax(self, i1max, w1, u1max, torque, with_mtpv=True, with_tmech=True, with_mtpa=True):
567
+ def iqd_imax_umax(self, i1max, w1, u1max, torque, with_mtpv=True,
568
+ with_tmech=True, with_mtpa=True):
591
569
  """return d-q current and shaft torque at stator frequency and max voltage
592
570
  and max current (for motor operation if maxtorque else generator operation)"""
593
571
  if torque > 0:
594
- sign=-1
572
+ sign = -1
595
573
  # -pi/2 --> 0
596
574
  b0, b1 = max(-np.pi/2, self.betarange[0]), 0
597
575
  if max(self.betarange) < b1:
598
576
  raise ValueError(
599
577
  f"invalid betarange for maxtorque>0: {self.betarange}")
600
578
  else:
601
- sign=1
579
+ sign = 1
602
580
  # -pi/2 --> -pi
603
581
  b0, b1 = -np.pi/2, max(-np.pi, self.betarange[0])
604
582
  if min(self.betarange) > b0:
@@ -608,6 +586,7 @@ class PmRelMachine(object):
608
586
  iq, id, _ = self.mtpa(i1max)
609
587
  else:
610
588
  iq, id = iqd(0, i1max)
589
+
611
590
  deps = 1e-6
612
591
  kmax = 100
613
592
 
@@ -622,8 +601,10 @@ class PmRelMachine(object):
622
601
  else:
623
602
  iq, id, tq = self.iqd_torque_umax(torque, w1, u1max)
624
603
  if not with_mtpv:
604
+ logging.debug("not mtpv iq %f id %f tq %f",
605
+ iq, id, tq)
625
606
  return iq, id, tq
626
- beta, i1 = betai1(iq, id)
607
+ #beta, i1 = betai1(iq, id)
627
608
  else:
628
609
  for k in range(kmax):
629
610
  bx = b0 + (b1-b0)/2
@@ -642,9 +623,9 @@ class PmRelMachine(object):
642
623
  if abs(du) > 0.1:
643
624
  logger.debug('oops? iqd_imax_umax one more torque reduction')
644
625
  if with_tmech:
645
- iq, id = self.iqd_tmech_umax(torque, w1, u1max)[:2]
626
+ iq, id, tq = self.iqd_tmech_umax(torque, w1, u1max)
646
627
  else:
647
- iq, id = self.iqd_torque_umax(torque, w1, u1max)[:2]
628
+ iq, id, tq = self.iqd_torque_umax(torque, w1, u1max)
648
629
  if with_mtpv:
649
630
  try:
650
631
  if with_tmech:
@@ -656,9 +637,26 @@ class PmRelMachine(object):
656
637
  iq, id, tq = self.mtpv(w1, u1max, iqd0=(iq, id),
657
638
  maxtorque=torque>0,
658
639
  i1max=i1max)
640
+ logging.debug("mtpv iq %f id %f tq %f",
641
+ iq, id, tq)
659
642
  return iq, id, tq
660
643
  except ValueError as e:
661
- logger.debug(e)
644
+ n = w1/2/np.pi/self.p
645
+ logger.debug(" i1max %f iq %f id %f", i1max, iq, id)
646
+ #
647
+ res = so.minimize(
648
+ lambda iqd: sign*self.tmech_iqd(*iqd, n),
649
+ (iq, id),
650
+ constraints=[{
651
+ 'type': 'eq',
652
+ 'fun': lambda iqd:
653
+ np.sqrt(2)*u1max - np.linalg.norm(
654
+ self.uqd(w1, *iqd))}])
655
+ logger.debug(" n %f i1max %f %f iq %f id %f tq %f",
656
+ 60*n, i1max, np.linalg.norm(res.x)/np.sqrt(2),
657
+ iq, id, sign*res.fun)
658
+ if res['success'] and abs(i1max*np.sqrt(2)) >= np.linalg.norm(res.x):
659
+ return *res.x, sign*res.fun
662
660
 
663
661
  if with_tmech:
664
662
  tq = self.tmech_iqd(iq, id, w1/2/np.pi/self.p)
@@ -723,6 +721,8 @@ class PmRelMachine(object):
723
721
  else:
724
722
  i0 = iqd0
725
723
  n = w1/2/np.pi/self.p
724
+ logger.debug("w1 %f u1 %f iqd0 %s maxtorque %s %f",
725
+ w1, u1, iqd0, maxtorque, i1max)
726
726
  constraints=[{'type': 'eq',
727
727
  'fun': lambda iqd:
728
728
  np.sqrt(2)*u1 - la.norm(
@@ -734,6 +734,7 @@ class PmRelMachine(object):
734
734
  res = so.minimize(lambda iqd: sign*self.tmech_iqd(*iqd, n), i0,
735
735
  method='SLSQP',
736
736
  constraints=constraints)
737
+ logger.debug("iq %f id %f w1 %f success %s", res.x[0], res.x[1], w1, res['success'])
737
738
  if res['success']:
738
739
  return res.x[0], res.x[1], sign*res.fun
739
740
  #logger.warning("w1=%.1f u1=%.1f maxtorque=%s %s: %s", w1, u1, maxtorque, res.x, res.message)
@@ -814,7 +815,7 @@ class PmRelMachine(object):
814
815
  if (abs(i1max) >= i1
815
816
  and round(u1max, 1) >= round(np.linalg.norm(
816
817
  self.uqd(w1max, iq, id)/np.sqrt(2)), 1)):
817
- return [w1type/2/np.pi/self.p, speedmax]
818
+ return [float(w1type/2/np.pi/self.p), float(speedmax)]
818
819
  wl, wu = [w1type, min(4*w1type, w1max)]
819
820
  if with_mtpv:
820
821
  kmax = 6
@@ -835,6 +836,7 @@ class PmRelMachine(object):
835
836
  T, with_mtpa=with_mtpa,
836
837
  with_mtpv=False)[:2]
837
838
  i1 = betai1(iq, id)[1]
839
+ logger.debug("iq %f id %f i1 %f", iq, id, i1)
838
840
  try:
839
841
  if with_tmech:
840
842
  def voltw1(wx):
@@ -851,7 +853,7 @@ class PmRelMachine(object):
851
853
  if ier == 1: #in (1, 4, 5):
852
854
  if abs(w[0]) <= wx:
853
855
  self.check_extrapolation = True
854
- return [w/2/np.pi/self.p
856
+ return [float(w/2/np.pi/self.p)
855
857
  for w in (w1type, w[0], w1max)] # ['MTPA', 'MTPV']
856
858
  if w[0] > wu:
857
859
  wl += (wu-wl)/4
@@ -873,7 +875,7 @@ class PmRelMachine(object):
873
875
  self.check_extrapolation = True
874
876
  w1max = min(w1max, np.floor(self.w1_umax(
875
877
  u1max, *iqd(-np.pi/2, abs(i1max)))))
876
- return [w/2/np.pi/self.p for w in (w1type, w1max)] # ['MTPA']
878
+ return [float(w/2/np.pi/self.p) for w in (w1type, w1max)] # ['MTPA']
877
879
 
878
880
 
879
881
  def operating_point(self, T, n, u1max, with_mtpa=True):
@@ -990,8 +992,8 @@ class PmRelMachine(object):
990
992
  if kwargs.get('i1max', 0):
991
993
  i1max = kwargs['i1max']
992
994
  w1, Tf = self.w1_imax_umax(i1max, u1max,
993
- with_mtpa=with_mtpa,
994
- with_tmech=with_tmech)
995
+ with_mtpa=with_mtpa,
996
+ with_tmech=with_tmech)
995
997
  if with_mtpa:
996
998
  iq, id, T = self.mtpa(i1max)
997
999
  else:
@@ -1026,7 +1028,8 @@ class PmRelMachine(object):
1026
1028
  iq, id = iqd(0, i1max)
1027
1029
 
1028
1030
  if with_tmech:
1029
- w1, Tf = self.w1_imax_umax(i1max, u1max, with_mtpa=with_mtpa,
1031
+ w1, Tf = self.w1_imax_umax(i1max, u1max,
1032
+ with_mtpa=with_mtpa,
1030
1033
  with_tmech=with_tmech)
1031
1034
  else:
1032
1035
  iq, id = self.iqd_torque(T)
@@ -1100,14 +1103,15 @@ class PmRelMachine(object):
1100
1103
  iq, id, tq = self.iqd_imax_umax(
1101
1104
  i1max, w1, u1max,
1102
1105
  tq, with_tmech=with_tmech,
1103
- with_mtpv=with_mtpv,
1104
1106
  with_mtpa=with_mtpa)
1105
1107
  else:
1106
1108
  if with_tmech:
1107
1109
  iq, id, tq = self.mtpv_tmech(w1, u1max,
1110
+ iqd0=(iq, id),
1108
1111
  maxtorque=T > 0)
1109
1112
  else:
1110
1113
  iq, id, tq = self.mtpv(w1, u1max,
1114
+ iqd0=(iq, id),
1111
1115
  maxtorque=T > 0)
1112
1116
  if (T > 0 and tq > 0) or (T < 0 and tq < 0):
1113
1117
  r['id'].append(id)
@@ -1115,8 +1119,8 @@ class PmRelMachine(object):
1115
1119
  r['n'].append(nn)
1116
1120
  r['T'].append(tq)
1117
1121
  else:
1118
- logger.warning("fieldweakening: n %g T %g tq %g i1max %g w1 %g u1 %g",
1119
- nn*60, T, tq, i1max, w1, u1max)
1122
+ logger.debug("fieldweakening: n %g T %g tq %g i1max %g w1 %g u1 %g",
1123
+ nn*60, T, tq, i1max, w1, u1max)
1120
1124
  except ValueError as e:
1121
1125
  nmax = r['n'][-1]
1122
1126
  logger.warning("%s: adjusted nmax %f T %f", e, nmax, r['T'][-1])
femagtools/machine/sm.py CHANGED
@@ -126,7 +126,7 @@ def parident(workdir, engine, machine,
126
126
  period_frac=kwargs.get('period_frac', 6),
127
127
  speed=kwargs.get('speed', 50))
128
128
 
129
- if kwargs.get("feloss", 0):
129
+ if kwargs.get("feloss", 0):
130
130
  simulation["feloss"] = kwargs["feloss"]
131
131
  machine["calc_fe_loss"] = loss_models[kwargs["feloss"].lower()]
132
132
  ###self.cleanup() # remove previously created files in workdir
@@ -413,8 +413,8 @@ class SynchronousMachine(object):
413
413
  def uqd(self, w1, iq, id, iex):
414
414
  """return uq, ud of frequency w1 and d-q current"""
415
415
  psid, psiq = self.psi(iq, id, iex)
416
- r1 = self.rstat(w1)
417
- return r1*iq + w1*psid, r1*id - w1*psiq
416
+ # r1 = self.rstat(w1)
417
+ return self.r1*iq + w1*(self.ls*id + psid), self.r1*id - w1*(self.ls*iq + psiq)
418
418
 
419
419
  def plcu1(self, iqde, w1):
420
420
  r1 = self.rstat(w1)
@@ -458,9 +458,9 @@ class SynchronousMachine(object):
458
458
  #options={'disp': disp, 'maxiter': maxiter})
459
459
  if res['success']:
460
460
  return res.x
461
- else:
461
+ else:
462
462
  res = so.minimize(
463
- lambda cur: (self.tmech_iqd(*cur, n) - torque)**2, res.x, method='SLSQP',
463
+ lambda cur: (self.tmech_iqd(*cur, n) - torque)**2, res.x, method='SLSQP',
464
464
  bounds=self.bounds,
465
465
  )
466
466
  if res['success']:
@@ -548,10 +548,10 @@ class SynchronousMachine(object):
548
548
  log(res.x)
549
549
  if res["success"]:
550
550
  return *res.x, self.tmech_iqd(*res.x, n)
551
- else:
551
+ else:
552
552
  # didn't converge, fullfill voltage and torque demand
553
553
  res = so.minimize(
554
- lambda cur: (self.tmech_iqd(*cur, n) - torque)**2, io, method='SLSQP',
554
+ lambda cur: (self.tmech_iqd(*cur, n) - torque)**2, io, method='SLSQP',
555
555
  bounds=self.bounds,
556
556
  constraints=[
557
557
  {'type': 'eq',
@@ -562,8 +562,8 @@ class SynchronousMachine(object):
562
562
  return *res.x, self.tmech_iqd(*res.x, n)
563
563
  else:
564
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',
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
567
  bounds=self.bounds,
568
568
  )
569
569
  return *res.x, self.tmech_iqd(*res.x, n)
@@ -680,7 +680,7 @@ class SynchronousMachine(object):
680
680
  Tf = T
681
681
  w1type = self.w1_umax(u1max, iq, id, iex)
682
682
  logger.debug("w1type %f", w1type)
683
- wmType = w1type/self.p
683
+ wmType = float(w1type/self.p)
684
684
  pmax = Tf*wmType
685
685
 
686
686
  def tload(wm):
@@ -723,7 +723,7 @@ class SynchronousMachine(object):
723
723
  iq, id, iex, tqx = self.iqd_torque_umax(
724
724
  tq, w1, u1max)
725
725
  tqx -= self.tfric
726
- else:
726
+ else:
727
727
  tqx = Tf
728
728
 
729
729
  uq, ud = self.uqd(w1, iq, id, iex)
@@ -857,9 +857,9 @@ class SynchronousMachinePsidq(SynchronousMachine):
857
857
  'rotor_hyst', 'rotor_eddy')}
858
858
 
859
859
  def set_max_iex(self, iexc):
860
- self.bounds[-1] = (self.bounds[-1][0], iexc)
860
+ self.bounds[-1] = (self.bounds[-1][0], iexc)
861
861
  self.exc_max = iexc
862
-
862
+
863
863
  def psi(self, iq, id, iex):
864
864
  """return psid, psiq of currents iq, id"""
865
865
  try:
@@ -980,9 +980,9 @@ class SynchronousMachineLdq(SynchronousMachine):
980
980
  'styoke_eddy', 'stteeth_eddy',
981
981
  'rotor_hyst', 'rotor_eddy')}
982
982
  pass
983
-
983
+
984
984
  def set_max_iex(self, iexc):
985
- self.bounds[-1] = (self.bounds[-1][0], iexc)
985
+ self.bounds[-1] = (self.bounds[-1][0], iexc)
986
986
  self.exc_max = iexc
987
987
 
988
988
  def psi(self, iq, id, iex):
femagtools/plot/bch.py CHANGED
@@ -515,10 +515,12 @@ def cogging(bch, title=''):
515
515
  fig.subplots_adjust(top=0.92)
516
516
 
517
517
 
518
- def demagnetization(demag, ax=0):
518
+ def demagnetization(demag, title='', ax=0):
519
519
  """plot rel. remanence vs. current"""
520
520
  if ax == 0:
521
521
  ax = plt.gca()
522
+ if title:
523
+ ax.set_title(title)
522
524
  scale = 1
523
525
  unit = 'A'
524
526
  if np.max(demag['i1']) > 25e3:
femagtools/plot/char.py CHANGED
@@ -304,23 +304,12 @@ def _plot_contour(speed, torque, z, ax, title='', levels=[],
304
304
  y, yscale = _normalize10(y, **kwargs)
305
305
 
306
306
  if not levels:
307
+ levels = [0.5, 0.7, 0.8]
307
308
  if max(z) <= 1:
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]
311
- levels = np.linspace(min(z),max(z),9)
312
- levels = np.round(levels, 2)
313
- levels = list(levels)
314
-
315
- else:
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)
321
-
322
- if max(z) > levels[-1]:
323
- levels.append(np.ceil(max(z)*100)/100)
309
+ a = np.array(z)
310
+ zmax = np.ceil(100*np.max(z))/100
311
+ levels += [zmax - x for x in
312
+ [0.07, 0.05, 0.03, 0.02, 0.01, 0]]
324
313
  else:
325
314
  levels = 14
326
315
  #