femagtools 1.8.18__py3-none-any.whl → 1.8.20__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.
@@ -646,7 +646,7 @@ class Machine(object):
646
646
  self.geom.set_virtual_start_end_corners()
647
647
 
648
648
  self.geom.looking_for_corners()
649
- create_areas = self.geom.analyse_airgap_line(is_inner)
649
+ create_areas = self.geom.close_outer_winding_areas()
650
650
  if self.geom.adjust_outer_hull_for_symmetry():
651
651
  create_areas = True
652
652
 
@@ -1284,6 +1284,30 @@ class Machine(object):
1284
1284
  def search_critical_elements(self, mindist):
1285
1285
  self.geom.search_critical_elements(mindist)
1286
1286
 
1287
+ def create_arc_element(self,
1288
+ radius,
1289
+ startangle,
1290
+ endangle):
1291
+ arc = Arc(Element(center=self.center,
1292
+ radius=radius,
1293
+ start_angle=startangle*180/np.pi,
1294
+ end_angle=endangle*180/np.pi),
1295
+ color='darkred',
1296
+ linestyle='dotted')
1297
+
1298
+ node1 = self.geom.find_the_node(arc.p1)
1299
+ if node1 is None:
1300
+ self.geom.split_with_point(arc.p1)
1301
+ node1 = self.geom.find_the_node(arc.p1)
1302
+ node2 = self.geom.find_the_node(arc.p2)
1303
+ if node2 is None:
1304
+ self.geom.split_with_point(arc.p2)
1305
+ node2 = self.geom.find_the_node(arc.p2)
1306
+ assert(node1 is not None)
1307
+ assert(node2 is not None)
1308
+ logger.debug("ARC Node1=%s, Node2=%s", node1, node2)
1309
+ self.geom.add_element(arc, rtol=1e-3, atol=1e-3)
1310
+
1287
1311
  def create_arc(self, radius,
1288
1312
  color='red', linestyle='dotted',
1289
1313
  attr=None):
@@ -1344,6 +1368,79 @@ class Machine(object):
1344
1368
  self.endangle)
1345
1369
  return self.geom.possible_magnet_in_the_middle(midangle)
1346
1370
 
1371
+ def separate_tooth_and_yoke(self, midangle):
1372
+ logger.debug("begin separate_tooth_and_yoke")
1373
+ wdg_list = self.geom.get_areas_of_type((AREA.TYPE_WINDINGS,))
1374
+ wdg_max_dist = 0.0
1375
+ wdg = None
1376
+ for w in wdg_list:
1377
+ if w.max_dist > wdg_max_dist:
1378
+ wdg_max_dist = w.max_dist
1379
+ wdg = w
1380
+
1381
+ tooth_list = self.geom.get_areas_of_type((AREA.TYPE_TOOTH,))
1382
+ tooth_max_dist = 0.0
1383
+ for tooth in tooth_list:
1384
+ tooth_max_dist = max(tooth_max_dist, tooth.max_dist)
1385
+ tooth_height = tooth_max_dist - self.geom.min_radius
1386
+ wdg_height = wdg_max_dist - self.geom.min_radius
1387
+
1388
+ logger.debug("HEIGHT TOOTH=%s, WINDINGS=%s", tooth_height, wdg_height)
1389
+
1390
+ if greater_equal(tooth_height, wdg_height * 0.9) and \
1391
+ less_equal(tooth_height, wdg_height * 1.1):
1392
+ logger.debug("Tooths are ok")
1393
+ return False # tooth ok
1394
+
1395
+ iron_list = self.geom.get_areas_of_irons()
1396
+ tooth_list = [iron for iron in iron_list
1397
+ if iron.close_to_ag and greater(iron.max_dist, wdg_max_dist, rtol=1e-2, atol=1e-2)]
1398
+ logger.debug("max winding dist = %s", wdg_max_dist)
1399
+ logger.debug("tooths = %s", len(tooth_list))
1400
+ wdg_nodes = [(distance(self.center, n), n) for n in wdg.list_of_nodes()]
1401
+ wdg_nodes.sort(reverse=True)
1402
+
1403
+ top_nodes = []
1404
+ other_nodes = []
1405
+ for d, n in wdg_nodes:
1406
+ if np.isclose(d, wdg.max_dist, rtol=1e-2, atol=1e-1):
1407
+ top_nodes.append((alpha_line(self.center, n), d, n))
1408
+ else:
1409
+ other_nodes.append((d, alpha_line(self.center, n), n))
1410
+
1411
+ a_right, d_right, n_right = (None, None, None)
1412
+ a_left, d_left, n_left = (None, None, None)
1413
+
1414
+ if not top_nodes:
1415
+ other_nodes.sort(reverse=True)
1416
+ for d, a, n in other_nodes:
1417
+ if a > midangle:
1418
+ if not a_left:
1419
+ a_left = a
1420
+ d_left = d
1421
+ n_left = n
1422
+ else:
1423
+ if not a_right:
1424
+ a_right = a
1425
+ d_right = d
1426
+ n_right = n
1427
+ if a_left and a_right:
1428
+ break
1429
+ if not (a_left and a_right):
1430
+ logger.debug("end separate_tooth_and_yoke: no arcs possible")
1431
+ return False # bad luck
1432
+ else:
1433
+ top_nodes.sort()
1434
+ a_right, d_right, n_right = top_nodes[0]
1435
+ a_left, d_left, n_left = top_nodes[0-1]
1436
+ node_right = self.geom.find_the_node(n_right)
1437
+ node_left = self.geom.find_the_node(n_left)
1438
+
1439
+ self.create_arc_element(d_right, self.startangle, a_right)
1440
+ self.create_arc_element(d_left, a_left, self.endangle)
1441
+ logger.debug("end separate_tooth_and_yoke")
1442
+ return True
1443
+
1347
1444
  def create_mirror_lines_outside_windings(self):
1348
1445
  logger.debug("create_mirror_lines_outside_windings")
1349
1446
 
@@ -1351,6 +1448,9 @@ class Machine(object):
1351
1448
  logger.debug("end create_mirror_lines_outside_windings: not done")
1352
1449
  return
1353
1450
 
1451
+ midangle = middle_angle(self.startangle, self.endangle)
1452
+ self.separate_tooth_and_yoke(midangle)
1453
+
1354
1454
  radius = self.radius+10
1355
1455
  ag_list = self.geom.detect_airgaps(self.center,
1356
1456
  self.startangle, self.endangle,
@@ -1359,7 +1459,6 @@ class Machine(object):
1359
1459
  radius_list = [(ag[0], (ag[0] + ag[1]) / 2, ag[1]) for ag in ag_list]
1360
1460
  radius_list.sort(reverse=True)
1361
1461
 
1362
- midangle = middle_angle(self.startangle, self.endangle)
1363
1462
  line = Line(
1364
1463
  Element(start=self.center,
1365
1464
  end=point(self.center, radius, midangle)))
@@ -1491,3 +1590,9 @@ class Machine(object):
1491
1590
  self.geom.check_airgap_connecting_nodes(m_outer.geom,
1492
1591
  self.startangle,
1493
1592
  self.endangle)
1593
+
1594
+ def remove_tiny_air_areas(self):
1595
+ if not self.geom.remove_tiny_air_areas():
1596
+ return False
1597
+ self.repair_hull()
1598
+ return True
femagtools/dxfsl/shape.py CHANGED
@@ -90,6 +90,13 @@ class Shape(object):
90
90
  self.n2 = n1
91
91
  self.n1 = n2
92
92
 
93
+ def has_same_nodes(self, e):
94
+ if points_are_close(e.n1, self.n1):
95
+ return points_are_close(e.n2, self.n2)
96
+ if points_are_close(e.n1, self.n2):
97
+ return points_are_close(e.n2, self.n1)
98
+ return False
99
+
93
100
  """an abstract geometry with 2 points"""
94
101
 
95
102
  def start(self):
femagtools/femag.py CHANGED
@@ -424,7 +424,7 @@ class BaseFemag(object):
424
424
  return sorted(pathlib.Path(self.workdir).glob('*.PROT'),
425
425
  key=lambda x: x.stat().st_mtime, reverse=True)[0].stem
426
426
 
427
- def readResult(self, machine, simulation, bch=None):
427
+ def readResult(self, simulation, bch=None, machine=None):
428
428
  if simulation:
429
429
  if simulation['calculationMode'] == "fieldcalc":
430
430
  nc = self.read_nc()
@@ -656,7 +656,7 @@ class Femag(BaseFemag):
656
656
  pass
657
657
 
658
658
  if simulation:
659
- return self.readResult(machine, simulation)
659
+ return self.readResult(machine=machine, simulation=simulation)
660
660
 
661
661
  return {'status': 'ok', 'message': self.modelname,
662
662
  'model': self.model.props()}
@@ -1196,6 +1196,6 @@ class ZmqFemag(BaseFemag):
1196
1196
  if r['status'] == 'ok':
1197
1197
  bch = femagtools.bch.Reader()
1198
1198
  bch.read(content.decode('latin1'))
1199
- bch = self.readResult(simulation, bch)
1199
+ bch = self.readResult(simulation=simulation, bch=bch)
1200
1200
  return bch
1201
1201
  raise FemagError(r['message'])
femagtools/isa7.py CHANGED
@@ -1359,28 +1359,31 @@ class Isa7(object):
1359
1359
  # prep dictionary for the loss calculation
1360
1360
  pm_data = []
1361
1361
  for i, se in enumerate(mag_spels):
1362
- ecp = [e.center for e in se.elements]
1363
- geometry = se.get_rect_geom()
1364
-
1365
- #= np.moveaxis(bxy, 1, 0)
1366
- pd = dict(name='pm_data_se' + str(se.key),
1367
- hm=geometry['h'],
1368
- wm=geometry['w'],
1369
- lm=self.arm_length,
1370
- alpha=geometry['alpha'],
1371
- ls=self.arm_length,
1372
- sigma=cond,
1373
- mur=mur,
1374
- loadcase=ibeta,
1375
- numpoles=poles,
1376
- elcp=transform_coord(geometry, ecp),
1377
- area=se.area(),
1378
- spel_key=se.key)
1379
- if ibeta != None:
1380
- pd.update({'bl': self.get_magnet_flux_density(se, icur, ibeta)})
1381
- pd.update(pos)
1382
-
1383
- pm_data.append(pd)
1362
+ try:
1363
+ ecp = [e.center for e in se.elements]
1364
+ geometry = se.get_rect_geom()
1365
+
1366
+ #= np.moveaxis(bxy, 1, 0)
1367
+ pd = dict(name='pm_data_se' + str(se.key),
1368
+ hm=geometry['h'],
1369
+ wm=geometry['w'],
1370
+ lm=self.arm_length,
1371
+ alpha=geometry['alpha'],
1372
+ ls=self.arm_length,
1373
+ sigma=cond,
1374
+ mur=mur,
1375
+ loadcase=ibeta,
1376
+ numpoles=poles,
1377
+ elcp=transform_coord(geometry, ecp),
1378
+ area=se.area(),
1379
+ spel_key=se.key)
1380
+ if ibeta != None:
1381
+ pd.update({'bl': self.get_magnet_flux_density(se, icur, ibeta)})
1382
+ pd.update(pos)
1383
+
1384
+ pm_data.append(pd)
1385
+ except IndexError as e:
1386
+ logger.warning("se %d magnet geometry ignored: %s", i, e)
1384
1387
  return pm_data
1385
1388
 
1386
1389
  def get_magnet_flux_density(self, se, icur, ibeta) -> list:
@@ -32,7 +32,7 @@ def create_from_eecpars(temp, eecpars, lfe=1, wdg=1):
32
32
  PM, EESM or IM"""
33
33
  rlfe = lfe
34
34
  rwdg = wdg
35
- opts = {k: eecpars[k] for k in ('zeta1', 'gam', 'kh', 'kpfe',
35
+ opts = {k: eecpars[k] for k in ('zeta1', 'gam', 'kh', 'kpfe', 'kpfe_s', 'kpfe_r',
36
36
  'kfric_b', 'kpmag') if k in eecpars}
37
37
  try:
38
38
  opts['rotor_mass'] = rlfe*eecpars['rotor_mass']
@@ -51,7 +51,7 @@ 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
54
+ # external inductances
55
55
  opts["ls"] = eecpars.get('ls1', 0)*rwdg**2
56
56
  if 'ldq' in smpars:
57
57
  machine = SynchronousMachineLdq(smpars, lfe=rlfe, wdg=rwdg, **opts)
@@ -372,6 +372,10 @@ def efficiency_losses_map(eecpars, u1, T, temp, n, npoints=(60, 40),
372
372
  if isinstance(m, PmRelMachine):
373
373
  plfe1 = m.kpfe*m.iqd_plfe1(*iqd, f1)
374
374
  plfe2 = m.kpfe*m.iqd_plfe2(iqd[0], iqd[1], f1)
375
+ if hasattr(m, 'kpfe_s'):
376
+ plfe1 = m.kpfe_s*m.iqd_plfe1(*iqd, f1)
377
+ if hasattr(m, 'kpfe_r'):
378
+ plfe2 = m.kpfe_r*m.iqd_plfe2(iqd[0], iqd[1], f1)
375
379
  plmag = m.kpmag*m.iqd_plmag(iqd[0], iqd[1], f1)
376
380
  plcu1 = m.iqd_plcu1(iqd[0], iqd[1], 2*np.pi*f1)
377
381
  plcu2 = m.iqd_plcu2(*iqd)
@@ -385,6 +389,10 @@ def efficiency_losses_map(eecpars, u1, T, temp, n, npoints=(60, 40),
385
389
  elif isinstance(m, SynchronousMachine):
386
390
  plfe1 = m.kpfe*m.iqd_plfe1(*iqd, f1)
387
391
  plfe2 = m.kpfe*m.iqd_plfe2(*iqd, f1)
392
+ if hasattr(m, 'kpfe_s'):
393
+ plfe1 = m.kpfe_s*m.iqd_plfe1(*iqd, f1)
394
+ if hasattr(m, 'kpfe_r'):
395
+ plfe2 = m.kpfe_r*m.iqd_plfe2(*iqd, f1)
388
396
  plmag = np.zeros_like(plfe2)
389
397
  plcu1 = m.iqd_plcu1(iqd[0], iqd[1], f1)
390
398
  try:
femagtools/machine/pm.py CHANGED
@@ -97,7 +97,7 @@ class PmRelMachine(object):
97
97
  self.zeta1 = 0.2
98
98
  self.gam = 0.7
99
99
  self.kh = 2
100
- self.kpfe = 1 # iron loss factor
100
+ self.kpfe = 1 # common iron loss factor
101
101
  self.kpmag = 1 # magnet loss factor
102
102
  self.kfric_b = 1
103
103
  self.rotor_mass = 0
@@ -181,9 +181,10 @@ class PmRelMachine(object):
181
181
  if np.abs(torque) < 1e-2:
182
182
  return (0, 0)
183
183
  if np.isscalar(iqd0):
184
- i0 = self.io
184
+ i0 = list(self.io)
185
185
  if torque<0:
186
186
  i0[0] = -i0[0]
187
+ i0 = tuple(i0)
187
188
  else:
188
189
  i0 = iqd0
189
190
  if with_mtpa:
@@ -258,7 +259,13 @@ class PmRelMachine(object):
258
259
  and friction windage losses"""
259
260
  if n > 1e-3:
260
261
  f1 = self.p*n
261
- plfe = self.kpfe * (self.iqd_plfe1(iq, id, f1) + self.iqd_plfe2(iq, id, f1))
262
+ plfe1 = self.kpfe * self.iqd_plfe1(iq, id, f1)
263
+ plfe2 = self.kpfe * self.iqd_plfe2(iq, id, f1)
264
+ if hasattr(self, 'kpfe_s'):
265
+ plfe1 = self.kpfe_s * self.iqd_plfe1(iq, id, f1)
266
+ if hasattr(self, 'kpfe_r'):
267
+ plfe2 = self.kpfe_r * self.iqd_plfe2(iq, id, f1)
268
+ plfe = plfe1 + plfe2
262
269
  pmag = self.kpmag * self.iqd_plmag(iq, id, f1)
263
270
  return (plfe + pmag + self.pfric(n))/(2*np.pi*n)
264
271
  return 0
@@ -927,10 +934,10 @@ class PmRelMachine(object):
927
934
  plfe1 = self.iqd_plfe1(iq, id, f1)
928
935
  plfe2 = self.iqd_plfe2(iq, id, f1)
929
936
  plmag = self.iqd_plmag(iq, id, f1)
930
- plfe = plfe1 + plfe2 + plmag
937
+ plfe = plfe1 + plfe2
931
938
  plfric = self.pfric(n)
932
939
  plcu = self.betai1_plcu(i1, 2 * np.pi * f1)
933
- pltotal = plfe + plcu + plfric
940
+ pltotal = plfe + plcu + plfric + plmag
934
941
  p1 = pmech + pltotal
935
942
  if np.abs(pmech) < 1e-12:
936
943
  eta = 0 # power to low for eta calculation
@@ -1153,11 +1160,15 @@ class PmRelMachine(object):
1153
1160
  f1 = np.array(r['n'])*self.p
1154
1161
  plfe1 = self.kpfe*self.iqd_plfe1(np.array(r['iq']), np.array(r['id']), f1)
1155
1162
  plfe2 = self.kpfe*self.iqd_plfe2(np.array(r['iq']), np.array(r['id']), f1)
1163
+ if hasattr(self, 'kpfe_s'):
1164
+ plfe1 = self.kpfe_s*self.iqd_plfe1(np.array(r['iq']), np.array(r['id']), f1)
1165
+ if hasattr(self, 'kpfe_r'):
1166
+ plfe2 = self.kpfe_r*self.iqd_plfe2(np.array(r['iq']), np.array(r['id']), f1)
1156
1167
  plmag = self.kpmag*self.iqd_plmag(np.array(r['iq']), np.array(r['id']), f1)
1157
- plfe = plfe1 + plfe2 + plmag
1168
+ plfe = plfe1 + plfe2
1158
1169
  plcu = self.betai1_plcu(np.array(r['i1']), 2*np.pi*f1)
1159
1170
  plfw = self.pfric(2*np.pi*f1)
1160
- pltotal = plfe + plcu + plfw
1171
+ pltotal = plfe + plcu + plfw + plmag
1161
1172
  r['pmech'] = pmech.tolist()
1162
1173
  r['plfe'] = plfe.tolist()
1163
1174
  r['plcu'] = plcu.tolist()
femagtools/machine/sm.py CHANGED
@@ -22,7 +22,7 @@ eecdefaults = {
22
22
  'tcu2': 20,
23
23
  'rotor_mass': 0,
24
24
  'kfric_b': 1,
25
- 'kpfe': 1 # iron loss factor
25
+ 'kpfe': 1 # common iron loss factor
26
26
  }
27
27
 
28
28
  logger = logging.getLogger('sm')
@@ -76,7 +76,13 @@ def parident(workdir, engine, machine,
76
76
  raise ValueError('i1_max missing')
77
77
  i1_max = kwargs['i1_max']
78
78
 
79
- ifnom = machine['rotor']['ifnom']
79
+
80
+ if "magnetFsl" in machine["magnet"]:
81
+ rotorkey = "magnet"
82
+ else:
83
+ rotorkey = "rotor"
84
+
85
+ ifnom = machine[rotorkey]['ifnom']
80
86
  exc_logspace = True
81
87
  ifmin, ifmax = ifnom/4, 1.4*ifnom
82
88
  if exc_logspace:
@@ -197,7 +203,7 @@ def parident(workdir, engine, machine,
197
203
  if simulation['calculationMode'] == 'ld_lq_fast':
198
204
  dqpars = dict(m=3, p=b['machine']['p'],
199
205
  r1=float(r1),
200
- r2=machine['rotor'].get('resistance', 1),
206
+ r2=machine[rotorkey].get('resistance', 1),
201
207
  rotor_mass=rotor_mass, kfric_b=1,
202
208
  ldq=[dict(
203
209
  ex_current=b['machine']['ex_current'],
@@ -214,7 +220,7 @@ def parident(workdir, engine, machine,
214
220
  else:
215
221
  dqpars = dict(m=3, p=b['machine']['p'],
216
222
  r1=r1,
217
- r2=machine['rotor'].get('resistance', 1),
223
+ r2=machine[rotorkey].get('resistance', 1),
218
224
  rotor_mass=rotor_mass, kfric_b=1,
219
225
  psidq=[dict(
220
226
  ex_current=b['machine']['ex_current'],
@@ -387,8 +393,13 @@ class SynchronousMachine(object):
387
393
  and friction windage losses"""
388
394
  if n > 1e-3:
389
395
  f1 = self.p*n
390
- plfe = self.kpfe * (self.iqd_plfe1(iq, id, iex, f1)
391
- + self.iqd_plfe2(iq, id, iex, f1))
396
+ plfe1 = self.kpfe * self.iqd_plfe1(iq, id, iex, f1)
397
+ plfe2 = self.kpfe * self.iqd_plfe2(iq, id, iex, f1)
398
+ if hasattr(self, 'kpfe_s'):
399
+ plfe1 = self.kpfe_s * self.iqd_plfe1(iq, id, iex, f1)
400
+ if hasattr(self, 'kpfe_r'):
401
+ plfe2 = self.kpfe_r * self.iqd_plfe2(iq, id, iex, f1)
402
+ plfe = plfe1 + plfe2
392
403
  return (plfe + self.pfric(n))/(2*np.pi*n)
393
404
  return 0
394
405
 
femagtools/mcv.py CHANGED
@@ -1173,7 +1173,10 @@ class MagnetizingCurve(object):
1173
1173
  mcv = self.find_by_name(name)
1174
1174
  if not mcv:
1175
1175
  bname = name
1176
- filename = ''.join((name, ext))
1176
+ filename = name if pathlib.Path(name).suffix.upper() == ext \
1177
+ else ''.join((name, ext))
1178
+ if name == 'dummy':
1179
+ return filename
1177
1180
  # check fillfac and readmcv
1178
1181
  if not fillfac or fillfac == 1.0:
1179
1182
  try:
femagtools/model.py CHANGED
@@ -477,8 +477,14 @@ class MachineModel(Model):
477
477
  model = {k: getattr(self, k) for k in keys if hasattr(self, k)}
478
478
  if hasattr(self, 'stator'):
479
479
  model['stator'] = {k: self.stator[k]
480
- for k in ('num_slots', 'num_slots_gen', 'slot_area')
480
+ for k in ('num_slots',
481
+ 'num_slots_gen',
482
+ 'slot_area')
481
483
  if k in self.stator}
484
+
485
+ for k in model:
486
+ if isinstance(model[k], np.float64):
487
+ model[k] = float(model[k])
482
488
  return model
483
489
 
484
490
  class FeaModel(Model):
@@ -108,11 +108,11 @@ def shortcircuit(femag, machine, bch, simulation, engine=0):
108
108
  bchsc.scData['demag'] = bchsc.demag
109
109
  if simulation.get('sim_demagn', 0):
110
110
  dd = {'displ': [d['displ']
111
- for d in bchsc.demag if 'displ' in d],
112
- 'H_max': [d['H_max']
113
- for d in bchsc.demag if 'H_max' in d],
114
- 'H_av': [d['H_av']
115
- for d in bchsc.demag if 'H_av' in d]}
111
+ for d in bchsc.demag if 'displ' in d],
112
+ 'H_max': [d['H_max']
113
+ for d in bchsc.demag if 'H_max' in d],
114
+ 'H_av': [d['H_av']
115
+ for d in bchsc.demag if 'H_av' in d]}
116
116
  x1 = bchsc.demag[0]['current_1']
117
117
  x2 = bchsc.demag[0]['current_2']
118
118
  def func(phi):
@@ -121,6 +121,7 @@ def shortcircuit(femag, machine, bch, simulation, engine=0):
121
121
  i1max = x1/np.cos(phi)
122
122
 
123
123
  phirot = dd['displ'][0]/180*np.pi
124
+ logger.info("i1max %g phi %g phirot %g", i1max, phi, phirot)
124
125
  bchsc.scData['demag'] = demag(
125
126
  femag, machine, simulation,
126
127
  i1max, phirot, phi, engine)
@@ -319,7 +320,7 @@ def shortcircuit_2phase(femag, machine, simulation, engine=0):
319
320
  # rotor position at maximum current:
320
321
  trot = min(iav[0], iap[0])
321
322
  phirot = wm*trot + phi0
322
- logger.info("phi %.1f")
323
+ logger.debug("phirot %.1f", phirot)
323
324
 
324
325
  scData = {
325
326
  'ia': ia.tolist(),
@@ -345,7 +346,7 @@ def demag(femag, machine, simulation, i1max, phirot, phi, engine=0):
345
346
  """demag simulation using psi-torq-rem-rot"""
346
347
  logger.info("Demagnetization processing")
347
348
  i1min = simulation.get('i1min', abs(i1max/3))
348
- num_steps = 7
349
+ num_steps = simulation.get('num_demag_cur_steps', 7)
349
350
  b = (i1min-abs(i1max))/np.log(i1min/abs(i1max))
350
351
  a = abs(i1max)/b
351
352
  xtab = np.linspace(i1min/abs(i1max),
@@ -82,14 +82,14 @@ rotate({
82
82
  mode = "save" -- save initial model state
83
83
  })
84
84
 
85
+ rotate({angle=phi, mode="absolute"})
86
+
85
87
  file_psi = io.open("psi-torq-rem.dat","w")
86
88
  for i=1, #curvec do
87
- print(string.format(" current: %d/%d %g, %g, %g\n",
88
- i, #curvec, curvec[i][1], curvec[i][2], curvec[i][3]))
89
-
90
- rotate({angle=phi, mode="absolute"})
91
89
  psi, tq, rr = calc_flux_torq_rem(curvec[i])
92
90
 
91
+ print(string.format(" current: %d/%d %g, %g, %g torque %g rr %g\n",
92
+ i, #curvec, curvec[i][1], curvec[i][2], curvec[i][3], tq, rr))
93
93
  file_psi:write(string.format("%g ", phi))
94
94
  for k=1, 3 do
95
95
  file_psi:write(string.format("%g ", curvec[i][k]))
@@ -0,0 +1,43 @@
1
+
2
+ m.yoke_diam = dy1
3
+ m.inside_diam = da1
4
+
5
+ m.wdg_location = -1 -- for gen_windings
6
+
7
+ m.slot_angle = ${model['slot_angle']*1e3}
8
+ m.slot_height = ${model['slot_height']*1e3}
9
+ m.slot_h1 = ${model['slot_h1']*1e3}
10
+ m.slot_h2 = ${model['slot_h2']*1e3}
11
+ m.slot_bk = ${model['slot_bk']*1e3}
12
+ m.slot_width = ${model['slot_width']*1e3}
13
+ m.slot_r1 = ${model['slot_r1']*1e3}
14
+ m.slot_r2 = ${model['slot_r2']*1e3}
15
+ m.middle_line = ${model.get('middle_line',0)}
16
+ m.tooth_width = ${model.get('tooth_width',0)*1e3}
17
+ m.slot_topwidth = ${model.get('slot_topwidth',0)*1e3}
18
+
19
+ m.zeroangl = ${model.get('zeroangle',0)}
20
+ m.rlength = ${model.get('rlength',1)*100}
21
+
22
+ % if model.get('ac_loss', False):
23
+ m.ac_loss = ${model.get('ac_loss', 6)}
24
+ % endif
25
+ m.mcvkey_yoke = mcvkey_yoke
26
+
27
+ pre_models("STATOR_KS1")
28
+
29
+ if mcvkey_teeth ~= nil then
30
+ if m.inside_diam > m.yoke_diam then
31
+ r = (m.inside_diam - m.slot_height)/2
32
+ else
33
+ r = (m.inside_diam + m.slot_height)/2
34
+ end
35
+ x0, y0 = pr2c(r, 2*math.pi/m.tot_num_slot + m.zeroangl/180*math.pi)
36
+ def_mat_fm_nlin(x0, y0, "blue", mcvkey_teeth, m.rlength)
37
+ end
38
+
39
+ %if model.get('thcond', 0) and model.get('thcap', 0):
40
+ stator_thcond = ${model.get('thcond', 24)}
41
+ stator_thcap = ${model.get('thcap', 480)}
42
+ stator_density = ${model.get('density', 7700)}
43
+ %endif
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: femagtools
3
- Version: 1.8.18
3
+ Version: 1.8.20
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