femagtools 1.7.6__py3-none-any.whl → 1.7.7__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/fsl.py CHANGED
@@ -42,7 +42,7 @@ class Builder:
42
42
  default_filters=['decode.utf8'])
43
43
 
44
44
  self.fsl_stator = False
45
- self.fsl_magnet = False
45
+ self.fsl_rotor = False
46
46
 
47
47
  def create_wdg_def(self, model):
48
48
  name = 'winding'
@@ -216,7 +216,7 @@ class Builder:
216
216
  .format(model.magnet.get('mcvkey_shaft', 'dummy'))]
217
217
 
218
218
  if 'magnetFsl' in model.magnet:
219
- self.fsl_magnet = True
219
+ self.fsl_rotor = True
220
220
  # obsolete
221
221
  if 'parameter' in model.magnet['magnetFsl']:
222
222
  return mcv + self.render_template(
@@ -242,10 +242,10 @@ class Builder:
242
242
  magmodel['mcvkey_magnet'] = model.get_mcvkey_magnet()
243
243
  if templ == 'dxf':
244
244
  return mcv + [
245
- u'xmag = {}',
246
- u'ymag = {}',
247
- u'mag_orient = {}',
248
- u'ndt(agndst)'] + model.magnet['dxf']['fsl']
245
+ 'xmag = {}',
246
+ 'ymag = {}',
247
+ 'mag_orient = {}',
248
+ 'ndt(agndst)'] + model.magnet['dxf']['fsl']
249
249
 
250
250
  return mcv + self.render_rotor(magmodel, templ)
251
251
 
@@ -267,12 +267,16 @@ class Builder:
267
267
  rotmodel['winding_inside'] = not model.external_rotor
268
268
  culosses = self.create_cu_losses(rotmodel, condMat)
269
269
 
270
- rotmodel.update(model.rotor[templ])
271
270
  rotmodel['is_rotor'] = True # just in case for the template
271
+ if templ == 'EESM':
272
+ if 'dxf' in rotmodel:
273
+ return mcv + ['ndt(agndst)'] + rotmodel['dxf']['fsl']
274
+ templ = 'rot_hsm'
275
+ rotmodel.update(model.rotor[templ])
272
276
  return mcv + culosses + self.render_rotor(rotmodel, templ)
273
277
 
274
278
  def create_rotor_winding(self, model):
275
- if hasattr(model, 'rotor') and model.rotortype() == 'rot_hsm':
279
+ if hasattr(model, 'rotor') and model.rotortype() == 'EESM':
276
280
  return self.render_rotor(model.rotor, 'rotor_winding')
277
281
  return []
278
282
 
@@ -306,21 +310,22 @@ class Builder:
306
310
 
307
311
  if templ == 'dxf':
308
312
  # reuse dxfsl model
309
- self.fsl_magnet = True
313
+ self.fsl_rotor = True
310
314
  if templ != 'dxffile':
311
315
  return
312
316
 
313
317
  from femagtools.dxfsl.converter import convert
314
318
  params = {}
315
- params['split'] = model.magnet[templ].get('split', False)
316
- params['show_plots'] = model.magnet[templ].get('plot', False)
319
+ rotor = model.magnet
320
+ params['split'] = rotor[templ].get('split', False)
321
+ params['show_plots'] = rotor[templ].get('plot', False)
317
322
  params['write_fsl'] = True
318
323
  params['airgap'] = -1.0
319
324
  pos = 'out' if model.external_rotor else 'in'
320
325
  params['part'] = ('rotor', pos)
321
326
  logger.info("Conv rotor from %s",
322
- model.magnet[templ]['name'])
323
- conv = convert(model.magnet[templ]['name'], **params)
327
+ rotor[templ]['name'])
328
+ conv = convert(rotor[templ]['name'], **params)
324
329
  model.set_value('poles', int(conv.get('num_poles')))
325
330
  self.set_diameter_parameter(model, conv)
326
331
  if model.get('da2'):
@@ -328,9 +333,9 @@ class Builder:
328
333
  ag = (model.get('bore_diam') - model.get('da2')/1e3)/2
329
334
  model.set_value('airgap', ag)
330
335
 
331
- model.magnet['dxf'] = dict(fsl=conv['fsl'])
332
- self.fsl_magnet = True
333
- del model.magnet[templ]
336
+ rotor['dxf'] = dict(fsl=conv['fsl'])
337
+ self.fsl_rotor = True
338
+ del rotor[templ]
334
339
 
335
340
  def render_rotor(self, magmodel, templ):
336
341
  fslcode = self.__render(magmodel, templ, magnet=True)
@@ -351,23 +356,25 @@ class Builder:
351
356
  if 'thcond' in model.stator:
352
357
  fslcmds += [
353
358
  '-- thermal properties in airgap',
354
- 'ag_cond = 0.063',
355
- 'thcap = 1007',
356
- 'beta = math.pi*m.npols_gen/m.num_poles + m.zeroangl/180*math.pi',
357
- 'xai, yai = pr2c((da1+da2)/4, beta)',
358
- 'def_mat_therm(xai,yai,"cyan",1.19,ag_cond,thcap,1)',
359
- 'xai, yai = pr2c((da1+da2)/4-ag/4, beta)',
360
- 'def_mat_therm(xai,yai,"cyan",1.19,ag_cond,thcap,1)',
361
- 'xai, yai = pr2c((da1+da2)/4+ag/4, beta)',
362
- 'def_mat_therm(xai,yai,"cyan",1.19,ag_cond,thcap,1)',
359
+ 'if m.zeroangl ~= nil then',
360
+ ' ag_cond = 0.063',
361
+ ' thcap = 1007',
362
+ ' beta = math.pi*m.npols_gen/m.num_poles + m.zeroangl/180*math.pi',
363
+ ' xai, yai = pr2c((da1+da2)/4, beta)',
364
+ ' def_mat_therm(xai,yai,"cyan",1.19,ag_cond,thcap,1)',
365
+ ' xai, yai = pr2c((da1+da2)/4-ag/4, beta)',
366
+ ' def_mat_therm(xai,yai,"cyan",1.19,ag_cond,thcap,1)',
367
+ ' xai, yai = pr2c((da1+da2)/4+ag/4, beta)',
368
+ ' def_mat_therm(xai,yai,"cyan",1.19,ag_cond,thcap,1)',
363
369
  '',
364
- 'state_of_problem("therm_static") -- thermic boundary conditions',
365
- 'x1,y1 = pd2c(dy2/2,m.zeroangl)',
366
- 'x2,y2 = pd2c(dy1/2,m.zeroangl)',
367
- 'beta = 360*m.npols_gen/m.num_poles',
368
- 'x3,y3 = pd2c(dy1/2,beta+m.zeroangl)',
369
- 'x4,y4 = pd2c(dy2/2,beta+m.zeroangl)',
370
- 'def_bcond_tp(x1,y1,x2,y2,x3,y3,x4,y4, 4)',
370
+ ' state_of_problem("therm_static") -- thermic boundary conditions',
371
+ ' x1,y1 = pd2c(dy2/2,m.zeroangl)',
372
+ ' x2,y2 = pd2c(dy1/2,m.zeroangl)',
373
+ ' beta = 360*m.npols_gen/m.num_poles',
374
+ ' x3,y3 = pd2c(dy1/2,beta+m.zeroangl)',
375
+ ' x4,y4 = pd2c(dy2/2,beta+m.zeroangl)',
376
+ ' def_bcond_tp(x1,y1,x2,y2,x3,y3,x4,y4, 4)',
377
+ 'end',
371
378
  'state_of_problem("mag_static")']
372
379
  return fslcmds
373
380
  return []
@@ -409,10 +416,10 @@ class Builder:
409
416
  cond = condMat.find(windings['material'])
410
417
  if not cond:
411
418
  raise FslBuilderError(
412
- 'conductor material {} not found'.format(
413
- windings['material']))
419
+ 'conductor material {} not found in {}'.format(
420
+ windings['material'], condMat))
414
421
  windings['cuconduct'] = cond['elconduct']
415
- for k in ('thcond', 'thcap'):
422
+ for k in ('thcond', 'thcap', 'spmaweight'):
416
423
  if k in cond:
417
424
  windings[k] = cond[k]
418
425
 
@@ -433,7 +440,14 @@ class Builder:
433
440
  return []
434
441
 
435
442
  def create_gen_winding(self, model):
436
- genwdg = self.__render(model, 'gen_winding')
443
+ try:
444
+ if model.winding['wire']['name'] == 'hairpin_winding':
445
+ model.winding['wire'].update(
446
+ {"num_layers": model.winding["num_layers"]})
447
+ genwdg = self.__render(model.winding,
448
+ 'gen_' + model.winding['wire'].get('name'))
449
+ except KeyError: # not hairpin_winding
450
+ genwdg = self.__render(model, 'gen_winding')
437
451
  k = list({'leak_dist_wind',
438
452
  'leak_evol_wind',
439
453
  'leak_tooth_wind'}.intersection(model.winding))
@@ -480,6 +494,9 @@ class Builder:
480
494
  params['airgap'] = model.dxffile.get('airgap', 0.0)
481
495
  params['nodedist'] = model.dxffile.get('nodedist', 1)
482
496
  params['full_model'] = model.dxffile.get('full_model', False)
497
+ params['EESM'] = model.dxffile.get('type', 'PMSM') == 'EESM'
498
+ if params['EESM']:
499
+ model.rotor['EESM'] = {}
483
500
  conv = convert(dxfname, **params)
484
501
 
485
502
  model.set_value('poles', conv.get('num_poles'))
@@ -492,6 +509,7 @@ class Builder:
492
509
  if not hasattr(model, 'stator'):
493
510
  setattr(model, 'stator', {})
494
511
  model.stator['num_slots'] = conv.get('tot_num_slot')
512
+ model.stator['slot_area'] = conv.get('slot_area')
495
513
  if model.get('num_agnodes', 0) == 0:
496
514
  model.set_value('agndst', conv['agndst']*1e-3)
497
515
  logger.info("num poles %d num slots %d outer diameter %.4f m agndst %.4f mm",
@@ -509,11 +527,17 @@ class Builder:
509
527
  if 'fsl_stator' in conv:
510
528
  self.fsl_stator = True
511
529
  model.stator['dxf'] = dict(fsl=conv['fsl_stator'])
512
- if not hasattr(model, 'magnet'):
513
- setattr(model, 'magnet', {})
514
- if 'fsl_magnet' in conv:
515
- self.fsl_magnet = True
516
- model.magnet['dxf'] = dict(fsl=conv['fsl_magnet'])
530
+ if not (hasattr(model, 'magnet') or hasattr(model, 'rotor')):
531
+ if params['EESM']:
532
+ setattr(model, 'rotor', {})
533
+ else:
534
+ setattr(model, 'magnet', {})
535
+ if 'fsl_rotor' in conv:
536
+ self.fsl_rotor = True
537
+ if hasattr(model, 'magnet'):
538
+ model.magnet['dxf'] = dict(fsl=conv['fsl_rotor'])
539
+ if hasattr(model, 'rotor'):
540
+ model.rotor['dxf'] = dict(fsl=conv['fsl_rotor'])
517
541
 
518
542
  def create_model(self, model, magnets=[], condMat=[], ignore_material=False):
519
543
  magnetMat = {}
@@ -563,10 +587,9 @@ class Builder:
563
587
  'remanenc', 1.2)
564
588
  model['magnet']['relperm'] = magnetMat.get('relperm', 1.05)
565
589
  model['magnet']['rlen'] = magnetMat.get('rlen', 1.0)
566
- for k in ('thcond', 'thcap'):
590
+ for k in ('spmaweight', 'thcond', 'thcap'):
567
591
  if k in magnetMat:
568
- model['magnet'][k] = magnetMat[k]
569
-
592
+ model['magnet'][k+'_magnet'] = magnetMat[k]
570
593
  rotor = (self.create_magnet(model) +
571
594
  self.create_magnet_model(model))
572
595
  if magnetMat:
@@ -714,11 +737,10 @@ class Builder:
714
737
  return self.__render(model, 'colorgrad')
715
738
 
716
739
  def mesh_airgap(self, model):
717
- if ((self.fsl_stator and self.fsl_magnet) or
740
+ if ((self.fsl_stator and self.fsl_rotor) or
718
741
  model.get('num_agnodes', 0)):
719
742
  return self.__render(model, 'mesh-airgap')
720
- else:
721
- return []
743
+ return []
722
744
 
723
745
  def create(self, model, sim, magnets=None, condMat=[]):
724
746
  "create model and analysis function"
@@ -768,10 +790,10 @@ class Builder:
768
790
 
769
791
  return (fslmodel + self.create_analysis(sim) +
770
792
  ['save_model("close")'])
771
-
772
- def create_detailed_wire(self, params, templ):
793
+
794
+ def create_detailed_wire(self, params, templ):
773
795
  return self.__render(params, templ)
774
-
796
+
775
797
  def __render(self, model, templ, stator=False, magnet=False):
776
798
  if templ.split('.')[-1] in ('fsl', 'mako'):
777
799
  try:
@@ -791,7 +813,7 @@ class Builder:
791
813
  if stator:
792
814
  self.fsl_stator = True
793
815
  if magnet:
794
- self.fsl_magnet = True
816
+ self.fsl_rotor = True
795
817
 
796
818
  return template.render_unicode(model=model).split('\n')
797
819
 
femagtools/isa7.py CHANGED
@@ -528,7 +528,7 @@ class Isa7(object):
528
528
 
529
529
  color = {1: [1.0, 0.0, 0.0], # RED
530
530
  2: [0.0, 1.0, 0.0], # GREEN
531
- 3: [1.0, 1.0, 0.0], # DARKYELLOW
531
+ 3: [1.0, 0.8, 0.0], # DARKYELLOW
532
532
  4: [0.0, 0.5019607843137255, 1.0], # BLUE
533
533
  5: [0.9803921568627451, 0.0, 1.0], # MAGENTA
534
534
  6: [0.0, 1.0, 0.8235294117647058], # CYAN
@@ -749,7 +749,7 @@ class Isa7(object):
749
749
  for e in self.elements])
750
750
 
751
751
  for a in ('FC_RADIUS', 'pole_pairs', 'poles_sim',
752
- 'delta_node_angle', 'speed',
752
+ 'layers', 'coil_span', 'delta_node_angle', 'speed',
753
753
  'MAGN_TEMPERATURE', 'BR_TEMP_COEF',
754
754
  'MA_SPEZ_WEIGHT', 'CU_SPEZ_WEIGHT'):
755
755
  v = getattr(reader, a, '')
@@ -323,6 +323,8 @@ def efficiency_losses_map(eecpars, u1, T, temp, n, npoints=(60, 40),
323
323
  plcu1 = m.iqd_plcu1(iqd[0], iqd[1], 2*np.pi*f1)
324
324
  plcu2 = m.iqd_plcu2(*iqd)
325
325
  tfric = m.tfric
326
+ logger.info("Iex %f %f",
327
+ np.min(iqd[2]), np.max(iqd[2]))
326
328
  else:
327
329
  plfe1 = np.array(r['plfe1'])
328
330
  plfe2 = np.zeros(ntmesh.shape[1])
femagtools/machine/pm.py CHANGED
@@ -141,6 +141,14 @@ class PmRelMachine(object):
141
141
  def rstat(self, w):
142
142
  """stator resistance
143
143
  """
144
+ if isinstance(self.zeta1, list):
145
+ logger.info("setup ac loss parameters...")
146
+ # polyfit from ac loss calculation
147
+ freq = w/2/np.pi
148
+ kr = self.zeta1[0]*freq**3 + self.zeta1[1]*freq**2 + \
149
+ self.zeta1[2]*freq + self.zeta1[3]
150
+ kr[kr<1] = 1.
151
+ return self.r1*(1 - self.kth1*(self.tcu1 - 20))*kr # ref 20°C
144
152
  if self.skin_resistance is not None:
145
153
  return self.skin_resistance(self.r1, w, self.tcu1, kth=self.kth1)
146
154
 
@@ -947,7 +955,7 @@ class PmRelMachine(object):
947
955
  i1max: max. phase current (RMS)
948
956
  """
949
957
  r = dict(id=[], iq=[], uq=[], ud=[], u1=[], i1=[], T=[],
950
- beta=[], gamma=[], phi=[], cosphi=[], pmech=[], n=[])
958
+ beta=[], gamma=[], phi=[], cosphi=[], pmech=[], n=[], type_op=[])
951
959
 
952
960
  if kwargs.get('i1max', 0):
953
961
  w1type, T = self.w1_imax_umax(kwargs['i1max'], u1max)
@@ -1032,6 +1040,7 @@ class PmRelMachine(object):
1032
1040
  r['n'].append(nx)
1033
1041
  r['T'].append(Tf)
1034
1042
 
1043
+ r['type_op'] = list(betai1(iq, id))
1035
1044
  Pmax = 2*np.pi*n1*Tf
1036
1045
  for ns, nu, iv in zip(nstab[1:], speedrange[2:], interv):
1037
1046
  # find id, iq, torque in fieldweakening range