femagtools 1.6.8__py3-none-any.whl → 1.7.1__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.
Files changed (51) hide show
  1. femagtools/__init__.py +2 -2
  2. femagtools/bch.py +1 -1
  3. femagtools/dxfsl/area.py +343 -406
  4. femagtools/dxfsl/areabuilder.py +139 -12
  5. femagtools/dxfsl/conv.py +27 -9
  6. femagtools/dxfsl/converter.py +406 -127
  7. femagtools/dxfsl/corner.py +3 -0
  8. femagtools/dxfsl/femparser.py +1 -1
  9. femagtools/dxfsl/fslrenderer.py +290 -246
  10. femagtools/dxfsl/functions.py +4 -2
  11. femagtools/dxfsl/geom.py +1204 -893
  12. femagtools/dxfsl/journal.py +58 -22
  13. femagtools/dxfsl/machine.py +254 -75
  14. femagtools/dxfsl/plotrenderer.py +38 -3
  15. femagtools/dxfsl/shape.py +380 -103
  16. femagtools/dxfsl/symmetry.py +679 -110
  17. femagtools/femag.py +27 -2
  18. femagtools/forcedens.py +65 -40
  19. femagtools/fsl.py +71 -28
  20. femagtools/losscoeffs.py +46 -0
  21. femagtools/machine/effloss.py +8 -1
  22. femagtools/machine/im.py +3 -1
  23. femagtools/machine/pm.py +11 -7
  24. femagtools/machine/sizing.py +15 -12
  25. femagtools/machine/sm.py +114 -33
  26. femagtools/machine/utils.py +38 -34
  27. femagtools/model.py +12 -2
  28. femagtools/moo/population.py +1 -1
  29. femagtools/parstudy.py +17 -1
  30. femagtools/plot/__init__.py +1 -1
  31. femagtools/plot/char.py +24 -7
  32. femagtools/plot/forcedens.py +56 -29
  33. femagtools/plot/mcv.py +4 -1
  34. femagtools/plot/phasor.py +6 -1
  35. femagtools/poc.py +17 -10
  36. femagtools/templates/cogg_calc.mako +7 -1
  37. femagtools/templates/displ_stator_rotor.mako +33 -0
  38. femagtools/templates/fieldcalc.mako +10 -16
  39. femagtools/templates/pm_sym_f_cur.mako +1 -1
  40. femagtools/tks.py +3 -9
  41. {femagtools-1.6.8.dist-info → femagtools-1.7.1.dist-info}/LICENSE +1 -0
  42. {femagtools-1.6.8.dist-info → femagtools-1.7.1.dist-info}/METADATA +7 -4
  43. {femagtools-1.6.8.dist-info → femagtools-1.7.1.dist-info}/RECORD +51 -50
  44. {femagtools-1.6.8.dist-info → femagtools-1.7.1.dist-info}/WHEEL +1 -1
  45. tests/engines/__init__.py +0 -20
  46. tests/geom/__init__.py +0 -20
  47. tests/moo/__init__.py +0 -20
  48. tests/test_model.py +8 -1
  49. tests/test_sizing.py +2 -2
  50. {femagtools-1.6.8.dist-info → femagtools-1.7.1.dist-info}/entry_points.txt +0 -0
  51. {femagtools-1.6.8.dist-info → femagtools-1.7.1.dist-info}/top_level.txt +0 -0
@@ -15,20 +15,33 @@ logger = logging.getLogger(__name__)
15
15
 
16
16
 
17
17
  def agndst(da1, da2, Q, p, nodedist=1):
18
- """ build agndst from set of useful number of nodes"""
18
+ """ build agndst from set of useful number of nodes
19
+ args:
20
+ da1: stator inner diameter
21
+ da2: rotor outer diameter
22
+ Q: number of stator slots
23
+ p: number of poles
24
+ nodedist: node distance factor
25
+ """
26
+ r = (da1 + da2)/4
27
+ ag = abs(da1 - da2)/6
19
28
  num_nodes = [30, 48, 60, 96, 120, 144, 180, 240, 288, 336, 360,
20
29
  432, 480]
21
- r = (da1 + da2)/4
22
30
  dagset = [2*np.pi/p/i for i in num_nodes]
23
- ag = abs(da1 - da2)/6
24
31
  i = max(np.argmin(np.abs(np.array(dagset) - np.arctan2(ag, r))), 1)
32
+ if p*num_nodes[i-1] % Q:
33
+ lcm = np.lcm(Q, p)//p
34
+ nmin, nmax = num_nodes[0]//lcm, num_nodes[-1]//lcm
35
+ num_nodes = [i*lcm for i in range(nmin, nmax) if i*lcm%6==0]
36
+ dagset = [2*np.pi/p/i for i in num_nodes]
37
+ i = max(np.argmin(np.abs(np.array(dagset) - np.arctan2(ag, r))), 1)
25
38
  nd = min(round(nodedist), i)
26
39
  try:
27
40
  logger.info("Num nodes/p %d Num nodes/slot %g nodedist %g",
28
41
  num_nodes[i-1], p*num_nodes[i-1]/Q, nodedist)
29
42
  if nodedist > 1:
30
43
  return dagset[i-nd]*r
31
- elif nodedist < 1 or i == 0:
44
+ if nodedist < 1 or i == 0:
32
45
  return dagset[i]*r
33
46
  except IndexError:
34
47
  pass
@@ -56,10 +69,10 @@ class FslRenderer(object):
56
69
  num = int(2*np.pi*radius)
57
70
  if num < 8:
58
71
  num = 8
59
- circle = [u'cx, cy = {}, {}'.format(center[0],
72
+ circle = ['cx, cy = {}, {}'.format(center[0],
60
73
  center[1]),
61
- u'nc_circle_m(cx,cy,{}, {})'.format(radius, num),
62
- u'create_mesh_se(cx, cy)\n']
74
+ 'nc_circle_m(cx,cy,{}, {})'.format(radius, num),
75
+ 'create_mesh_se(cx, cy)\n']
63
76
  self.content += circle
64
77
 
65
78
  def arc(self, startangle, endangle, center, radius,
@@ -154,78 +167,79 @@ class FslRenderer(object):
154
167
  d_percent = min(1.0, d / dist)
155
168
  if ndt_list[n][0] < d_percent:
156
169
  self.agndst = ndt_list[n][1] * self.agndst
157
- self.content.append(u'\nndt({}*agndst)\n'.
170
+ self.content.append('\nndt({}*agndst)\n'.
158
171
  format(ndt_list[n][1]))
159
172
  while ndt_list[n][0] < d_percent:
160
173
  n += 1
161
174
  e.render(self)
162
175
 
163
- self.content.append(u'\n')
176
+ self.content.append('\n')
164
177
 
165
178
  parts = int(machine.get_symmetry_part())
166
- self.content += [u'-- parts = {}'.format(parts)]
179
+ self.content += ['-- parts = {}'.format(parts)]
167
180
  if geom.is_stator():
168
181
  if machine.get_num_slots() > 0:
169
182
  self.content += [
170
- u'-- num_slots = {}'.format(
183
+ '-- num_slots = {}'.format(
171
184
  machine.get_num_slots())
172
185
  ]
173
- self.content += [u'-- min_radius = {}'.format(geom.min_radius),
174
- u'-- max_radius = {}'.format(geom.max_radius),
175
- u'-- min_corner = {}, {}'.format(
186
+ self.content += ['-- min_radius = {}'.format(geom.min_radius),
187
+ '-- max_radius = {}'.format(geom.max_radius),
188
+ '-- min_corner = {}, {}'.format(
176
189
  geom.start_min_corner(0),
177
190
  geom.start_min_corner(1)),
178
- u'-- max_corner = {}, {}'.format(
191
+ '-- max_corner = {}, {}'.format(
179
192
  geom.start_max_corner(0),
180
193
  geom.start_max_corner(1)),
181
- u'\n']
194
+ '\n']
182
195
  if inner:
183
- self.content += [u'inner_da_start = {}'
196
+ self.content += ['inner_da_start = {}'
184
197
  .format(geom.dist_start_max_corner()),
185
- u'inner_da_end = {}'
198
+ 'inner_da_end = {}'
186
199
  .format(geom.dist_end_max_corner())]
187
200
  if outer:
188
201
  slice = 1 if machine.is_mirrored() else 2
189
202
  self.content += [
190
- u'-- create air layer outside',
191
- u'x0, y0 = {}, {}'.format(
203
+ '-- create air layer outside',
204
+ 'x0, y0 = {}, {}'.format(
192
205
  geom.start_max_corner(0),
193
206
  geom.start_max_corner(1)),
194
- u'hair = 1.0',
195
- u'parts = {}'.format(machine.get_num_parts()),
196
- u'r1 = {} + hair'.format(geom.max_radius),
197
- u'r, phi = c2pr(x0, y0)',
198
- u'x1, y1 = pr2c(r1, phi)',
199
- u'x2, y2 = pr2c(r1, {}*math.pi/parts)'.format(slice),
200
- u'x3, y3 = pr2c(r, {}*math.pi/parts)'.format(slice),
201
- u'nc_line(x0, y0, x1, y1, 0)',
202
- u'nc_circle_m(x1, y1, x2, y2, 0.0, 0.0, 0)',
203
- u'nc_line(x2, y2, x3, y3, 0)',
204
- u'x0, y0 = pr2c(r1 - hair/2, math.pi/parts)',
205
- u'create_mesh_se(x0, y0)',
206
- u'\n',
207
- u'outer_da_start = {}'.format(
207
+ 'hair = 1.0',
208
+ 'parts = {}'.format(machine.get_num_parts()),
209
+ 'r1 = {} + hair'.format(geom.max_radius),
210
+ 'r, phi = c2pr(x0, y0)',
211
+ 'x1, y1 = pr2c(r1, phi)',
212
+ 'x2, y2 = pr2c(r1, {}*math.pi/parts)'.format(slice),
213
+ 'x3, y3 = pr2c(r, {}*math.pi/parts)'.format(slice),
214
+ 'nc_line(x0, y0, x1, y1, 0)',
215
+ 'nc_circle_m(x1, y1, x2, y2, 0.0, 0.0, 0)',
216
+ 'nc_line(x2, y2, x3, y3, 0)',
217
+ 'x0, y0 = pr2c(r1 - hair/2, math.pi/parts)',
218
+ 'create_mesh_se(x0, y0)',
219
+ '\n',
220
+ 'outer_da_start = {}'.format(
208
221
  geom.dist_start_min_corner()),
209
- u'outer_da_end = {}'.format(
222
+ 'outer_da_end = {}'.format(
210
223
  geom.dist_end_min_corner())
211
224
  ]
212
225
 
213
- self.content += [u'\n',
214
- u'xmag = {}',
215
- u'ymag = {}',
216
- u'mag_orient = {}',
217
- u'mag_exists = 0',
218
- u'if mcvkey_yoke == nil then',
219
- u' mcvkey_yoke = "dummy"',
220
- u'end',
221
- u'x0_iron_tooth, y0_iron_tooth = 0.0, 0.0',
222
- u'x0_iron_yoke, y0_iron_yoke = 0.0, 0.0',
223
- u'x0_shaft, y0_shaft = 0.0, 0.0',
224
- u'\n']
226
+ self.content += ['\n',
227
+ 'xmag = {}',
228
+ 'ymag = {}',
229
+ 'mag_orient = {}',
230
+ 'mag_exists = 0',
231
+ 'if mcvkey_yoke == nil then',
232
+ ' mcvkey_yoke = "dummy"',
233
+ 'end',
234
+ 'x0_iron_tooth, y0_iron_tooth = 0.0, 0.0',
235
+ 'x0_iron_yoke, y0_iron_yoke = 0.0, 0.0',
236
+ 'x0_shaft, y0_shaft = 0.0, 0.0',
237
+ '\n']
225
238
 
226
239
  subregions = {}
227
240
  num_windings = 0
228
241
  num_magnets = 0
242
+ magor = []
229
243
  for area in geom.list_of_areas():
230
244
  if area.number_of_elements() > 1:
231
245
  p = area.get_point_inside(geom)
@@ -238,51 +252,55 @@ class FslRenderer(object):
238
252
  if area.type not in subregions:
239
253
  subregions[area.type] = 1
240
254
  num_windings += 1
241
- self.content.append(u'm.xcoil_{}, m.ycoil_{} = x0, y0'.
255
+ self.content.append('m.xcoil_{}, m.ycoil_{} = x0, y0'.
242
256
  format(num_windings, num_windings))
243
257
 
244
258
  elif area.is_magnet():
245
259
  if area.type not in subregions:
246
260
  subregions[area.type] = 1
247
261
  num_magnets += 1
248
- self.content.append(u'xmag[{}], ymag[{}] = x0, y0'.
262
+ self.content.append('xmag[{}], ymag[{}] = x0, y0'.
249
263
  format(num_magnets, num_magnets))
250
- self.content.append(u'mag_orient[{}] = {}'.
264
+ self.content.append('mag_orient[{}] = {}'.
251
265
  format(num_magnets, area.phi))
266
+ magor.append([p[0], p[1], area.phi]) # must correct rotation?
252
267
 
253
268
  elif area.type > 0:
254
269
  if area.type in subregions:
255
270
  self.content.append(
256
- u'add_to_subreg(x0, y0, "{}")'.
271
+ 'add_to_subreg(x0, y0, "{}")'.
257
272
  format(area.name()))
258
273
  else:
259
274
  subregions[area.type] = 1
275
+ color = area.color()
276
+ if color == 'cyan':
277
+ color = 'skyblue'
260
278
  self.content.append(
261
- u'def_new_subreg(x0, y0, "{}", "{}")'.
262
- format(area.name(), area.color()))
279
+ 'def_new_subreg(x0, y0, "{}", "{}")'.
280
+ format(area.name(), color))
263
281
  if area.is_stator_iron_yoke():
264
282
  self.content.append(
265
- u'x0_iron_yoke, y0_iron_yoke = x0, y0')
283
+ 'x0_iron_yoke, y0_iron_yoke = x0, y0')
266
284
  elif area.is_stator_iron_tooth():
267
285
  self.content.append(
268
- u'x0_iron_tooth, y0_iron_tooth = x0, y0')
286
+ 'x0_iron_tooth, y0_iron_tooth = x0, y0')
269
287
  elif area.is_rotor_iron():
270
288
  self.content.append(
271
- u'x0_iron_yoke, y0_iron_yoke = x0, y0')
289
+ 'x0_iron_yoke, y0_iron_yoke = x0, y0')
272
290
  elif area.is_shaft():
273
291
  self.content.append(
274
- u'x0_shaft, y0_shaft = x0, y0')
292
+ 'x0_shaft, y0_shaft = x0, y0')
275
293
 
276
294
  self.content.append(u"\n")
277
295
 
278
296
  txt = [u"if x0_iron_yoke > 0.0 then",
279
297
  u" if mcvkey_yoke ~= 'dummy' then",
280
- u' def_mat_fm_nlin(x0_iron_yoke, y0_iron_yoke, "blue", mcvkey_yoke, 100)',
281
- u' else',
282
- u' def_mat_fm(x0_iron_yoke, y0_iron_yoke, ur, 100)',
283
- u' end',
284
- u'end\n']
285
- self.content.append(u'\n'.join(txt))
298
+ ' def_mat_fm_nlin(x0_iron_yoke, y0_iron_yoke, "blue", mcvkey_yoke, 100)',
299
+ ' else',
300
+ ' def_mat_fm(x0_iron_yoke, y0_iron_yoke, ur, 100)',
301
+ ' end',
302
+ 'end\n']
303
+ self.content.append('\n'.join(txt))
286
304
 
287
305
  txt = [u"if x0_iron_tooth > 0.0 then",
288
306
  u" if(x0_iron_yoke == 0 and mcvkey_yoke ~= 'dummy') then",
@@ -294,89 +312,97 @@ class FslRenderer(object):
294
312
  u" def_mat_fm(x0_iron_tooth, y0_iron_tooth, ur, 100)",
295
313
  u" end",
296
314
  u" end",
297
- u'end\n']
298
- self.content.append(u'\n'.join(txt))
315
+ 'end\n']
316
+ self.content.append('\n'.join(txt))
299
317
 
300
318
  txt = [u"if x0_shaft > 0.0 then",
301
319
  u" if mcvkey_shaft ~= 'dummy' then",
302
- u' def_mat_fm_nlin(x0_shaft, y0_shaft, "lightgrey", mcvkey_shaft, 100)',
303
- u' else',
304
- u' def_mat_fm(x0_shaft, y0_shaft, ur, 100)',
305
- u' end',
306
- u'end\n']
307
- self.content.append(u'\n'.join(txt))
320
+ ' def_mat_fm_nlin(x0_shaft, y0_shaft, "lightgrey", mcvkey_shaft, 100)',
321
+ ' else',
322
+ ' def_mat_fm(x0_shaft, y0_shaft, ur, 100)',
323
+ ' end',
324
+ 'end\n']
325
+ self.content.append('\n'.join(txt))
308
326
 
309
327
  if num_windings > 0:
310
328
  if geom.is_mirrored():
311
329
  self.content += [
312
- u'r, phi = c2pr(m.xcoil_1, m.ycoil_1)',
313
- u'm.xcoil_2, m.ycoil_2 = pr2c(r, {}*2.0 - phi)'.format(geom.alfa)]
314
- self.content.append(u'm.wdg_location = 1.0 -- stator\n')
330
+ 'r, phi = c2pr(m.xcoil_1, m.ycoil_1)',
331
+ 'm.xcoil_2, m.ycoil_2 = pr2c(r, {}*2.0 - phi)'.format(geom.alfa)]
332
+ self.content.append('m.wdg_location = 1 -- stator\n')
315
333
 
316
334
  if num_magnets > 0:
317
- self.content.append(u'mag_exists = {}'.
335
+ self.content.append('mag_exists = {}'.
318
336
  format(num_magnets))
319
337
  if geom.is_mirrored():
320
- self.content.append(u'mag_mirrored = true')
338
+ self.content.append('mag_mirrored = true')
321
339
  else:
322
- self.content.append(u'mag_mirrored = false')
323
- self.content.append(u'mag_alpha = {}\n'
340
+ self.content.append('mag_mirrored = false')
341
+ self.content.append('mag_alpha = {}\n'
324
342
  .format(geom.get_alfa()))
325
343
 
326
344
  if geom.is_mirrored():
327
- self.content.append(u'-- mirror')
328
- self.content.append(u'mirror_nodechains({}, {}, {}, {})\n'.format(
345
+ self.content.append('-- mirror')
346
+ self.content.append('mirror_nodechains({}, {}, {}, {})\n'.format(
329
347
  geom.mirror_corners[1][0], # max x1
330
348
  geom.mirror_corners[1][1], # max y1
331
349
  geom.mirror_corners[0][0], # min x2
332
350
  geom.mirror_corners[0][1])) # min y2
333
351
 
334
- self.content.append(u'parts_gen = {}'.format(geom.num_variable()))
352
+ self.content.append('parts_gen = {}'.format(geom.num_variable()))
335
353
 
336
354
  # angle after mirroring
337
- self.content.append(u'alfa = {}\n'.format(geom.get_alfa()))
355
+ self.content.append('alfa = {}\n'.format(geom.get_alfa()))
338
356
 
339
- self.content += [u'-- rotate',
340
- u'x1, y1 = {}, {}'.format(
357
+ self.content += ['-- rotate',
358
+ 'x1, y1 = {}, {}'.format(
341
359
  geom.start_corners[0][0],
342
360
  geom.start_corners[0][1])] # min xy1
343
361
  if outer:
344
- self.content.append(u'x2, y2 = pr2c(r1, 0.0)')
362
+ self.content.append('x2, y2 = pr2c(r1, 0.0)')
345
363
  else:
346
- self.content.append(u'x2, y2 = {}, {}'.format(
364
+ self.content.append('x2, y2 = {}, {}'.format(
347
365
  geom.start_corners[1][0],
348
366
  geom.start_corners[1][1])) # max xy1
349
367
 
350
368
  if geom.is_mirrored():
351
- self.content.append(u'x3, y3 = pr2c(x2, alfa)')
352
- self.content.append(u'x4, y4 = pr2c(x1, alfa)')
353
- else:
354
- self.content += [u'x3, y3 = pr2c(r1, 2*math.pi/m.tot_num_slot+phi)',
355
- u'x4, y4 = {}, {}'.format(
369
+ self.content.append('x3, y3 = pr2c(x2, alfa)')
370
+ self.content.append('x4, y4 = pr2c(x1, alfa)')
371
+ elif outer:
372
+ self.content += ['x3, y3 = pr2c(r1, 2*math.pi/parts+phi)',
373
+ 'x4, y4 = {}, {}'.format(
356
374
  geom.end_corners[0][0],
357
375
  geom.end_corners[0][1])] # min xy4
376
+ else:
377
+ self.content += ['x3, y3 = {}, {}'.format(
378
+ geom.end_corners[-1][0],
379
+ geom.end_corners[-1][1]), # min xy3
380
+ 'x4, y4 = {}, {}'.format(
381
+ geom.end_corners[0][0],
382
+ geom.end_corners[0][1]), # min xy4
383
+ 'def_bcond_vpo(x4, y4, x1, y1)']
358
384
 
359
- self.content.append(u'if parts_gen > 1 then')
385
+ self.content.append('if parts_gen > 1 then')
360
386
  if geom.corners_dont_match():
361
- txt = [u' -- Warning: corners dont match',
362
- u' mirror_nodechains(x3, y3, x4, y4)',
363
- u' if {} > 2 then'.format(geom.num_variable()),
364
- u' my_alfa = alfa * 2',
365
- u' x3, y3 = pr2c(x2, my_alfa)',
366
- u' x4, y4 = pr2c(x1, my_alfa)',
367
- u' n = {} / 2'.format(geom.num_variable()),
368
- u' rotate_copy_nodechains(x1,y1,x2,y2,x3,y3,x4,y4,n-1)',
369
- u' end']
370
- self.content.append(u'\n'.join(txt))
387
+ txt = [' -- Warning: corners dont match',
388
+ ' mirror_nodechains(x3, y3, x4, y4)',
389
+ ' if {} > 2 then'.format(geom.num_variable()),
390
+ ' my_alfa = alfa * 2',
391
+ ' x3, y3 = pr2c(x2, my_alfa)',
392
+ ' x4, y4 = pr2c(x1, my_alfa)',
393
+ ' n = {} / 2'.format(geom.num_variable()),
394
+ ' rotate_copy_nodechains(x1,y1,x2,y2,x3,y3,x4,y4,n-1)',
395
+ ' end']
396
+ self.content.append('\n'.join(txt))
371
397
  else:
372
398
  self.content.append(
373
- u' rotate_copy_nodechains(x1,y1,x2,y2,x3,y3,x4,y4,parts_gen-1)')
374
- self.content.append(u'end')
399
+ ' rotate_copy_nodechains(x1,y1,x2,y2,x3,y3,x4,y4,parts_gen-1)')
400
+ self.content.append('end')
375
401
 
376
- self.content.append(u'alfa = parts_gen * alfa\n')
402
+ self.content.append('alfa = parts_gen * alfa\n')
377
403
 
378
404
  if self.fm_nlin:
379
- self.content.append(u'\nx0, y0 = {}, {}'. format(
405
+ self.content.append('\nx0, y0 = {}, {}'. format(
380
406
  self.fm_nlin[0], self.fm_nlin[1]))
381
407
 
382
408
  mat = [u"if fm_nlin_mcvfile ~= 'dummy' then",
@@ -388,66 +414,77 @@ class FslRenderer(object):
388
414
  u"else",
389
415
  u" def_mat_fm(x0,y0, 1000.0, fm_nlin_rlen)",
390
416
  u"end"]
391
- self.content.append(u'\n'.join(mat))
417
+ self.content.append('\n'.join(mat))
392
418
 
393
419
  if self.shaft:
394
- mat = [u'\nif shaft_mat==1 then',
395
- u' def_mat_fm_nlin(0.1,0.1,"lightgrey",fm_nlin_mcvfile_shft,fm_nlin_rlen)',
396
- u'end']
397
- self.content.append(u'\n'.join(mat))
420
+ mat = ['\nif shaft_mat==1 then',
421
+ ' def_mat_fm_nlin(0.1,0.1,"lightgrey",fm_nlin_mcvfile_shft,fm_nlin_rlen)',
422
+ 'end']
423
+ self.content.append('\n'.join(mat))
398
424
 
399
425
  if num_magnets:
426
+ # TODO: this is clearly a hack to adapt the mag orientation
427
+ # for cases where magnets have multiple small slices
428
+ rotangle = 0
429
+ mag = np.array(magor)
430
+ x, y = mag.T[:2]
431
+ if np.allclose(mag.T[2] - np.arctan2(y, x), np.pi/2, atol=2e-2):
432
+ # all angles are 90°
433
+ rotangle = 90
400
434
  self.content += [
401
- u'-- pm magnets',
402
- u'if mag_exists > 0 then',
403
- u' if( m.remanenc == nil ) then',
404
- u' m.remanenc = 1.15',
405
- u' m.relperm = 1.05',
406
- u' end',
407
- u' if( m.orient == nil ) then',
408
- u' m.orient = m.parallel',
409
- u' end',
410
- u' if( m.magncond == nil ) then',
411
- u' m.magncond = 625000.0',
412
- u' end',
413
- u' if( m.rlen == nil ) then',
414
- u' m.rlen = 100',
415
- u' end',
416
- u' for i=0, m.npols_gen-1 do',
417
- u' for n=1, mag_exists do',
418
- u' r, p = c2pr(xmag[n], ymag[n])',
419
- u' x0, y0 = pr2c(r, i*mag_alpha+p)',
420
- u' phi = (i*mag_alpha+mag_orient[n])*180/math.pi',
421
- u' if ( i % 2 == 0 ) then',
422
- u' phi = phi - 180',
423
- u' color = "red"',
424
- u' else',
425
- u' color = "green"',
426
- u' end',
427
- u' if(m.mcvkey_magnet == nil) then',
428
- u' def_mat_pm(x0, y0, color, m.remanenc, m.relperm,',
429
- u' phi, m.orient, m.magncond, m.rlen)',
430
- u' else',
431
- u' def_mat_pm_nlin(x0, y0, color, m.mcvkey_magnet,',
432
- u' phi, m.orient, m.magncond, m.rlen)',
433
- u' end',
434
- u' if mag_mirrored then',
435
- u' x0, y0 = pr2c(r, (i+1)*mag_alpha-p)',
436
- u' phi = ((i+1)*mag_alpha-mag_orient[n])*180/math.pi',
437
- u' if ( i % 2 == 0 ) then',
438
- u' phi = phi - 180',
439
- u' end',
440
- u' if(m.mcvkey_magnet == nil) then',
441
- u' def_mat_pm(x0, y0, color, m.remanenc, m.relperm,',
442
- u' phi, m.orient, m.magncond, m.rlen)',
443
- u' else',
444
- u' def_mat_pm_nlin(x0, y0, color, m.mcvkey_magnet,',
445
- u' phi, m.orient, m.magncond, m.rlen)',
446
- u' end',
447
- u' end',
448
- u' end',
449
- u' end',
450
- u'end']
435
+ '-- pm magnets',
436
+ 'if mag_exists > 0 then',
437
+ ' if( m.remanenc == nil ) then',
438
+ ' m.remanenc = 1.15',
439
+ ' m.relperm = 1.05',
440
+ ' end',
441
+ ' if( m.orient == nil ) then',
442
+ ' m.orient = m.parallel',
443
+ ' end',
444
+ ' if( m.magncond == nil ) then',
445
+ ' m.magncond = 625000.0',
446
+ ' end',
447
+ ' if( m.rlen == nil ) then',
448
+ ' m.rlen = 100',
449
+ ' end',
450
+ ' for i=0, m.npols_gen-1 do',
451
+ ' for n=1, mag_exists do',
452
+ ' r, p = c2pr(xmag[n], ymag[n])',
453
+ ' x0, y0 = pr2c(r, i*mag_alpha+p)',
454
+ ' phi = (i*mag_alpha+mag_orient[n])*180/math.pi',
455
+ ' if ( i % 2 == 0 ) then',
456
+ f' phi = phi - {rotangle}',
457
+ ' color = "red"',
458
+ ' else',
459
+ f' phi = phi - {rotangle} + 180',
460
+ ' color = "green"',
461
+ ' end',
462
+ ' if(m.mcvkey_magnet == nil) then',
463
+ ' def_mat_pm(x0, y0, color, m.remanenc, m.relperm,',
464
+ ' phi, m.orient, m.magncond, m.rlen)',
465
+ ' else',
466
+ ' def_mat_pm_nlin(x0, y0, color, m.mcvkey_magnet,',
467
+ ' phi, m.orient, m.magncond, m.rlen)',
468
+ ' end',
469
+ ' if mag_mirrored then',
470
+ ' x0, y0 = pr2c(r, (i+1)*mag_alpha-p)',
471
+ ' phi = ((i+1)*mag_alpha-mag_orient[n])*180/math.pi',
472
+ ' if ( i % 2 == 0 ) then',
473
+ f' phi = phi - {rotangle}',
474
+ ' else',
475
+ f' phi = phi - {rotangle} + 180',
476
+ ' end',
477
+ ' if(m.mcvkey_magnet == nil) then',
478
+ ' def_mat_pm(x0, y0, color, m.remanenc, m.relperm,',
479
+ ' phi, m.orient, m.magncond, m.rlen)',
480
+ ' else',
481
+ ' def_mat_pm_nlin(x0, y0, color, m.mcvkey_magnet,',
482
+ ' phi, m.orient, m.magncond, m.rlen)',
483
+ ' end',
484
+ ' end',
485
+ ' end',
486
+ ' end',
487
+ 'end']
451
488
 
452
489
  return self.content
453
490
 
@@ -461,95 +498,102 @@ class FslRenderer(object):
461
498
  logger.warning("ERROR: Rotor or Stator missing")
462
499
  return []
463
500
 
501
+ if params['external_rotor']:
502
+ stator = inner
503
+ rotor = outer
504
+ else:
505
+ stator = outer
506
+ rotor = inner
507
+
464
508
  num_layers = min(m_inner.num_of_layers() +
465
509
  m_outer.num_of_layers(),
466
510
  2)
467
511
  self.agndst = params.get('agndst', 0.1)
468
512
  return [
469
- u'-- generated from DXF by femagtools {}'.format(__version__),
470
- u'exit_on_error = false',
471
- u'exit_on_end = false',
472
- u'verbosity = 2\n',
473
- u'new_model_force("{}","Test")'.format(self.model),
474
- u'global_unit(mm)',
475
- u'pickdist(0.001)',
476
- u'cosys(polar)\n',
477
- u'dy1 = {}'.format(params.get('dy1', 0.0)),
478
- u'da1 = {}'.format(params.get('da1', 0.0)),
479
- u'dy2 = {}'.format(params.get('dy2', 0.0)),
480
- u'da2 = {}'.format(params.get('da2', 0.0)),
481
- u'ag = (da1 - da2)/2\n',
482
- u'm.tot_num_slot = {}'.format(params.get('tot_num_slot', 0)),
483
- u'm.num_sl_gen = {}'.format(params.get('num_sl_gen', 0)),
484
- u'm.num_poles = {}'.format(params.get('num_poles', 0)),
485
- u'm.num_pol_pair = m.num_poles/2',
486
- u'm.num_slots = m.num_sl_gen',
487
- u'm.npols_gen = m.num_poles * m.num_sl_gen / m.tot_num_slot',
488
- u'm.tot_num_sl = m.tot_num_slot',
489
- u'm.fc_radius = (da1+da2)/4',
490
- u'm.fc_radius1 = m.fc_radius',
491
- u'm.arm_length = 1.0',
492
- u'pre_models("basic_modpar")\n',
493
- u'm.airgap = 2*ag/3',
494
- u'm.nodedist = 1.0',
495
- u'agndst = {}'.format(self.agndst),
496
- u"mcvkey_teeth = 'dummy'",
497
- u"mcvkey_yoke = 'dummy'",
498
- u"mcvkey_shaft = 'dummy'",
499
- u"ur = 1000.0",
500
- u"ndt(agndst)"] + outer + [
501
- u"mcvkey_teeth = 'dummy'",
502
- u"mcvkey_yoke = 'dummy'",
503
- u"mcvkey_shaft = 'dummy'",
504
- u"ndt(agndst)"] + inner + [
505
- u'-- airgap',
506
- u'ndt(agndst)',
507
- u'r1 = m.fc_radius - ag/6',
508
- u'x1, y1 = pr2c(r1, alfa)',
509
- u'n = math.floor(r1*alfa/agndst + 1.5)',
510
- u'nc_circle_m(r1, 0, x1, y1, 0.0, 0.0, n)\n',
511
- u'r2 = m.fc_radius + ag/6',
512
- u'x2, y2 = pr2c(r2, alfa)',
513
- u'nc_circle_m(r2, 0, x2, y2, 0.0, 0.0, n)\n',
514
- u'if inner_da_start == nil then',
515
- u' inner_da_start = da2/2',
516
- u'end',
517
- u'x1, y1 = pr2c(inner_da_start, 0.0)',
518
- u'nc_line(x1, y1, r1, 0.0, 0.0)\n',
519
- u'if outer_da_start == nil then',
520
- u' outer_da_start = da1/2',
521
- u'end',
522
- u'x2, y2 = pr2c(outer_da_start, 0.0)',
523
- u'nc_line(r2, 0.0, x2, y2, 0.0)\n',
524
- u'if m.tot_num_slot > m.num_sl_gen then',
525
- u' x3, y3 = pr2c(inner_da_end, alfa)',
526
- u' x4, y4 = pr2c(r1, alfa)',
527
- u' nc_line(x3, y3, x4, y4, 0, 0)\n',
528
- u' x3, y3 = pr2c(outer_da_end, alfa)',
529
- u' x4, y4 = pr2c(r2, alfa)',
530
- u' nc_line(x3, y3, x4, y4, 0, 0)',
531
- u'end\n',
532
- u'x0, y0 = pr2c(r1-ag/6, alfa/2)',
533
- u'create_mesh_se(x0, y0)',
534
- u'x0, y0 = pr2c(r2+ag/6, alfa/2)',
535
- u'create_mesh_se(x0, y0)\n',
536
- u'connect_models()\n',
537
- u'-- Gen_winding',
538
- u'if m.xcoil_1 ~= nil then',
539
- u' m.num_phases = 3',
540
- u' m.num_layers = {}'.format(num_layers),
541
- u' m.num_wires = 1',
542
- u' m.coil_span = {}'.format(
513
+ '-- generated from DXF by femagtools {}'.format(__version__),
514
+ 'exit_on_error = false',
515
+ 'exit_on_end = false',
516
+ 'verbosity = 2\n',
517
+ 'new_model_force("{}","Test")'.format(self.model),
518
+ 'global_unit(mm)',
519
+ 'pickdist(0.001)',
520
+ 'cosys(polar)\n',
521
+ 'dy1 = {}'.format(params.get('dy1', 0.0)),
522
+ 'da1 = {}'.format(params.get('da1', 0.0)),
523
+ 'dy2 = {}'.format(params.get('dy2', 0.0)),
524
+ 'da2 = {}'.format(params.get('da2', 0.0)),
525
+ 'ag = (da1 - da2)/2\n',
526
+ 'm.tot_num_slot = {}'.format(params.get('tot_num_slot', 0)),
527
+ 'm.num_sl_gen = {}'.format(params.get('num_sl_gen', 0)),
528
+ 'm.num_poles = {}'.format(params.get('num_poles', 0)),
529
+ 'm.num_pol_pair = m.num_poles/2',
530
+ 'm.num_slots = m.num_sl_gen',
531
+ 'm.npols_gen = m.num_poles * m.num_sl_gen / m.tot_num_slot',
532
+ 'm.tot_num_sl = m.tot_num_slot',
533
+ 'm.fc_radius = (da1+da2)/4',
534
+ 'm.fc_radius1 = m.fc_radius',
535
+ 'm.arm_length = 1.0',
536
+ 'pre_models("basic_modpar")\n',
537
+ 'm.airgap = 2*ag/3',
538
+ 'm.nodedist = 1.0',
539
+ 'agndst = {}'.format(self.agndst),
540
+ "mcvkey_teeth = 'dummy'",
541
+ "mcvkey_yoke = 'dummy'",
542
+ "mcvkey_shaft = 'dummy'",
543
+ "ur = 1000.0",
544
+ "ndt(agndst)"] + stator + [
545
+ "mcvkey_teeth = 'dummy'",
546
+ "mcvkey_yoke = 'dummy'",
547
+ "mcvkey_shaft = 'dummy'",
548
+ "ndt(agndst)"] + rotor + [
549
+ '-- airgap',
550
+ 'ndt(agndst)',
551
+ 'r1 = m.fc_radius - ag/6',
552
+ 'x1, y1 = pr2c(r1, alfa)',
553
+ 'n = math.floor(r1*alfa/agndst + 1.5)',
554
+ 'nc_circle_m(r1, 0, x1, y1, 0.0, 0.0, n)\n',
555
+ 'r2 = m.fc_radius + ag/6',
556
+ 'x2, y2 = pr2c(r2, alfa)',
557
+ 'nc_circle_m(r2, 0, x2, y2, 0.0, 0.0, n)\n',
558
+ 'if inner_da_start == nil then',
559
+ ' inner_da_start = da2/2',
560
+ 'end',
561
+ 'x1, y1 = pr2c(inner_da_start, 0.0)',
562
+ 'nc_line(x1, y1, r1, 0.0, 0.0)\n',
563
+ 'if outer_da_start == nil then',
564
+ ' outer_da_start = da1/2',
565
+ 'end',
566
+ 'x2, y2 = pr2c(outer_da_start, 0.0)',
567
+ 'nc_line(r2, 0.0, x2, y2, 0.0)\n',
568
+ 'if m.tot_num_slot > m.num_sl_gen then',
569
+ ' x3, y3 = pr2c(inner_da_end, alfa)',
570
+ ' x4, y4 = pr2c(r1, alfa)',
571
+ ' nc_line(x3, y3, x4, y4, 0, 0)\n',
572
+ ' x3, y3 = pr2c(outer_da_end, alfa)',
573
+ ' x4, y4 = pr2c(r2, alfa)',
574
+ ' nc_line(x3, y3, x4, y4, 0, 0)',
575
+ 'end\n',
576
+ 'x0, y0 = pr2c(r1-ag/6, alfa/2)',
577
+ 'create_mesh_se(x0, y0)',
578
+ 'x0, y0 = pr2c(r2+ag/6, alfa/2)',
579
+ 'create_mesh_se(x0, y0)\n',
580
+ 'connect_models()\n',
581
+ '-- Gen_winding',
582
+ 'if m.xcoil_1 ~= nil then',
583
+ ' m.num_phases = 3',
584
+ ' m.num_layers = {}'.format(num_layers),
585
+ ' m.num_wires = 1',
586
+ ' m.coil_span = {}'.format(
543
587
  params.get(
544
588
  'tot_num_slot', 1)//params.get('num_poles', 1)),
545
- u' m.current = 0.0',
546
- u' m.mat_type = 1.0 -- rotating',
547
- u' m.wind_type = 1.0 -- winding & current',
548
- u' m.win_asym = 1.0 -- sym',
549
- u' m.wdg_location = 1.0 -- stator',
550
- u' m.curr_inp = 0.0 -- const',
551
- u' m.dq_offset = 0',
552
- u' pre_models("Gen_winding")',
553
- u' pre_models("gen_pocfile")',
554
- u'end\n',
555
- u'save_model(cont)\n']
589
+ ' m.current = 0.0',
590
+ ' m.mat_type = 1.0 -- rotating',
591
+ ' m.wind_type = 1.0 -- winding & current',
592
+ ' m.win_asym = 1.0 -- sym',
593
+ ' m.wdg_location = 1.0 -- stator',
594
+ ' m.curr_inp = 0.0 -- const',
595
+ ' m.dq_offset = 0',
596
+ ' pre_models("Gen_winding")',
597
+ ' pre_models("gen_pocfile")',
598
+ 'end\n',
599
+ 'save_model(cont)\n']