femagtools 1.7.5__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.
Files changed (38) hide show
  1. femagtools/__init__.py +1 -1
  2. femagtools/bch.py +11 -1
  3. femagtools/dxfsl/area.py +108 -7
  4. femagtools/dxfsl/conv.py +15 -0
  5. femagtools/dxfsl/converter.py +44 -20
  6. femagtools/dxfsl/fslrenderer.py +93 -42
  7. femagtools/dxfsl/functions.py +8 -0
  8. femagtools/dxfsl/geom.py +126 -18
  9. femagtools/dxfsl/machine.py +30 -9
  10. femagtools/femag.py +3 -3
  11. femagtools/fsl.py +73 -48
  12. femagtools/isa7.py +2 -2
  13. femagtools/machine/effloss.py +2 -0
  14. femagtools/machine/pm.py +198 -42
  15. femagtools/machine/sm.py +294 -253
  16. femagtools/machine/utils.py +5 -14
  17. femagtools/model.py +32 -2
  18. femagtools/moo/algorithm.py +6 -0
  19. femagtools/nc.py +2 -0
  20. femagtools/opt.py +2 -1
  21. femagtools/plot/bch.py +19 -5
  22. femagtools/plot/char.py +4 -4
  23. femagtools/plot/nc.py +21 -4
  24. femagtools/plot/wdg.py +38 -26
  25. femagtools/templates/gen_hairpin_winding.mako +209 -0
  26. femagtools/templates/gen_winding.mako +8 -9
  27. femagtools/templates/magnetIron.mako +32 -6
  28. femagtools/templates/mesh-airgap.mako +9 -0
  29. femagtools/templates/rotor_winding.mako +10 -6
  30. femagtools/templates/statorRotor3.mako +8 -5
  31. femagtools/windings.py +31 -18
  32. {femagtools-1.7.5.dist-info → femagtools-1.7.7.dist-info}/METADATA +1 -1
  33. {femagtools-1.7.5.dist-info → femagtools-1.7.7.dist-info}/RECORD +38 -37
  34. {femagtools-1.7.5.dist-info → femagtools-1.7.7.dist-info}/WHEEL +1 -1
  35. tests/test_windings.py +1 -1
  36. {femagtools-1.7.5.dist-info → femagtools-1.7.7.dist-info}/LICENSE +0 -0
  37. {femagtools-1.7.5.dist-info → femagtools-1.7.7.dist-info}/entry_points.txt +0 -0
  38. {femagtools-1.7.5.dist-info → femagtools-1.7.7.dist-info}/top_level.txt +0 -0
@@ -9,6 +9,7 @@
9
9
  """
10
10
  import numpy as np
11
11
  from .shape import Shape
12
+ from .area import TYPE_TOOTH, TYPE_YOKE
12
13
  import logging
13
14
  from .. import __version__
14
15
  logger = logging.getLogger(__name__)
@@ -52,12 +53,13 @@ def agndst(da1, da2, Q, p, nodedist=1):
52
53
  class FslRenderer(object):
53
54
  """a model that can created by FSL"""
54
55
 
55
- def __init__(self, name):
56
+ def __init__(self, name, mtype):
56
57
  self.model = name
57
58
  self.mirror_axis = None
58
59
  self.fm_nlin = None
59
60
  self.shaft = None
60
61
  self.agndst = 1
62
+ self.mtype = mtype
61
63
 
62
64
  def mirror_nodechains(self, p0, p1):
63
65
  self.mirror_axis = np.array((p0, p1)).ravel().tolist()
@@ -91,7 +93,7 @@ class FslRenderer(object):
91
93
  p2 = (center[0] + radius*np.cos(endangle),
92
94
  center[1] + radius*np.sin(endangle))
93
95
  self.content.append(
94
- u"nc_circle_m({}, {}, {}, {}, {}, {}, {})".format(
96
+ "nc_circle_m({}, {}, {}, {}, {}, {}, {})".format(
95
97
  p1[0], p1[1], p2[0], p2[1],
96
98
  center[0], center[1], num))
97
99
 
@@ -118,7 +120,7 @@ class FslRenderer(object):
118
120
  n0 = nodes[0]
119
121
  for n1 in nodes[1:]:
120
122
  self.content.append(
121
- u"nc_line({}, {}, {}, {}, {}) -- ellipse".format(
123
+ "nc_line({}, {}, {}, {}, {}) -- ellipse".format(
122
124
  n0[0], n0[1], n1[0], n1[1], 0))
123
125
  n0 = n1
124
126
 
@@ -134,12 +136,12 @@ class FslRenderer(object):
134
136
  return
135
137
  if e.has_attribute('auxline'):
136
138
  self.content.append(
137
- u"nc_line({}, {}, {}, {}, {}) -- auxiliary".format(
139
+ "nc_line({}, {}, {}, {}, {}) -- auxiliary".format(
138
140
  p1[0], p1[1], p2[0], p2[1], num))
139
141
  return
140
142
 
141
143
  self.content.append(
142
- u"nc_line({}, {}, {}, {}, {})".format(
144
+ "nc_line({}, {}, {}, {}, {})".format(
143
145
  p1[0], p1[1], p2[0], p2[1], num))
144
146
 
145
147
  def sorted_elements(self, geom, inner=False):
@@ -156,10 +158,21 @@ class FslRenderer(object):
156
158
  '''create fsl statements with nodechains'''
157
159
  machine.set_alfa_and_corners()
158
160
  geom = machine.geom
159
- geom.split_lines_longer_than(geom.max_radius/4)
161
+ split_len = (geom.max_radius - geom.min_radius) / 4
162
+ geom.split_all_lines_longer_than(split_len)
160
163
  self.content = []
161
164
 
162
- ndt_list = [(0.2, 1.5), (0.45, 2), (0.7, 3.0), (1.1, 3.0)]
165
+ ndt_list = [(0.00, 1.1),
166
+ (0.05, 1.5),
167
+ (0.10, 1.7),
168
+ (0.15, 2.0),
169
+ (0.20, 2.3),
170
+ (0.30, 2.7),
171
+ (0.40, 3.1),
172
+ (0.50, 3.5),
173
+ (0.70, 4.5),
174
+ (0.85, 5.5),
175
+ (1.10, 5.5)]
163
176
  dist = geom.max_radius - geom.min_radius
164
177
  el_sorted = self.sorted_elements(geom, inner)
165
178
 
@@ -184,6 +197,15 @@ class FslRenderer(object):
184
197
  '-- num_slots = {}'.format(
185
198
  machine.get_num_slots())
186
199
  ]
200
+ # fix stator subregions
201
+ sregs = [a.type for a in geom.list_of_areas()
202
+ if a.type in (TYPE_YOKE, TYPE_TOOTH)]
203
+ if len(sregs) > 0 and set(sregs) == {TYPE_TOOTH}:
204
+ for a in geom.list_of_areas():
205
+ if a.type == TYPE_TOOTH:
206
+ a.type = TYPE_YOKE
207
+ logger.debug("FIXED STATOR SUBREGION")
208
+
187
209
  self.content += ['-- min_radius = {}'.format(geom.min_radius),
188
210
  '-- max_radius = {}'.format(geom.max_radius),
189
211
  '-- min_corner = {}, {}'.format(
@@ -224,14 +246,16 @@ class FslRenderer(object):
224
246
  'outer_da_end = {}'.format(
225
247
  geom.dist_end_min_corner())
226
248
  ]
227
-
228
- self.content += ['\n',
249
+ if self.mtype == 'PMSM':
250
+ self.content += [
229
251
  'xmag = {}',
230
252
  'ymag = {}',
231
- 'mag_orient = {}',
253
+ 'mag_orient = {}']
254
+ self.content += ['\n',
232
255
  'mag_exists = 0',
233
256
  'if mcvkey_yoke == nil then',
234
257
  ' mcvkey_yoke = "dummy"',
258
+ ' ur = 1000.0',
235
259
  'end',
236
260
  'x0_iron_tooth, y0_iron_tooth = 0.0, 0.0',
237
261
  'x0_iron_yoke, y0_iron_yoke = 0.0, 0.0',
@@ -242,20 +266,27 @@ class FslRenderer(object):
242
266
  num_windings = 0
243
267
  num_magnets = 0
244
268
  magor = []
269
+
245
270
  for area in geom.list_of_areas():
246
271
  if area.number_of_elements() > 1:
247
272
  p = area.get_point_inside(geom)
248
273
  if p:
249
- self.content.append(u"x0, y0 = {}, {}".format(p[0], p[1]))
250
- # self.content.append(u"point(x0, y0, red, 4)") # for debugging
251
- self.content.append(u"create_mesh_se(x0, y0)")
274
+ self.content.append("x0, y0 = {}, {}".format(p[0], p[1]))
275
+ # self.content.append("point(x0, y0, red, 4)") # for debugging
276
+ self.content.append("create_mesh_se(x0, y0)")
252
277
 
253
278
  if area.is_winding():
254
279
  if area.type not in subregions:
255
280
  subregions[area.type] = 1
256
- num_windings += 1
257
- self.content.append('m.xcoil_{}, m.ycoil_{} = x0, y0'.
258
- format(num_windings, num_windings))
281
+ if self.mtype == 'PMSM' or outer:
282
+ num_windings += 1
283
+ rmin, rmax = area.minmax_dist_from_center((0,0))
284
+ self.content.append(
285
+ f'rcoil_{num_windings} = {rmin}, {rmax}')
286
+ self.content.append('m.xcoil_{}, m.ycoil_{} = x0, y0'.
287
+ format(num_windings, num_windings))
288
+ else:
289
+ self.content.append('m.xcoil_r, m.ycoil_r = x0, y0')
259
290
 
260
291
  elif area.is_magnet():
261
292
  if area.type not in subregions:
@@ -293,10 +324,10 @@ class FslRenderer(object):
293
324
  self.content.append(
294
325
  'x0_shaft, y0_shaft = x0, y0')
295
326
 
296
- self.content.append(u"\n")
327
+ self.content.append("\n")
297
328
 
298
- txt = [u"if x0_iron_yoke > 0.0 then",
299
- u" if mcvkey_yoke ~= 'dummy' then",
329
+ txt = ["if x0_iron_yoke > 0.0 then",
330
+ " if mcvkey_yoke ~= 'dummy' then",
300
331
  ' def_mat_fm_nlin(x0_iron_yoke, y0_iron_yoke, "blue", mcvkey_yoke, 100)',
301
332
  ' else',
302
333
  ' def_mat_fm(x0_iron_yoke, y0_iron_yoke, ur, 100)',
@@ -304,21 +335,21 @@ class FslRenderer(object):
304
335
  'end\n']
305
336
  self.content.append('\n'.join(txt))
306
337
 
307
- txt = [u"if x0_iron_tooth > 0.0 then",
308
- u" if(x0_iron_yoke == 0 and mcvkey_yoke ~= 'dummy') then",
309
- u" def_mat_fm_nlin(x0_iron_tooth, y0_iron_tooth, 'blue', mcvkey_yoke, 100)",
310
- u" else",
311
- u" if (mcvkey_teeth ~= 'dummy' and mcvkey_teeth ~= nil) then",
312
- u" def_mat_fm_nlin(x0_iron_tooth, y0_iron_tooth, 'blue', mcvkey_teeth, 100)",
313
- u" else",
314
- u" def_mat_fm(x0_iron_tooth, y0_iron_tooth, ur, 100)",
315
- u" end",
316
- u" end",
338
+ txt = ["if x0_iron_tooth > 0.0 then",
339
+ " if(x0_iron_yoke == 0 and mcvkey_yoke ~= 'dummy') then",
340
+ " def_mat_fm_nlin(x0_iron_tooth, y0_iron_tooth, 'blue', mcvkey_yoke, 100)",
341
+ " else",
342
+ " if (mcvkey_teeth ~= 'dummy' and mcvkey_teeth ~= nil) then",
343
+ " def_mat_fm_nlin(x0_iron_tooth, y0_iron_tooth, 'blue', mcvkey_teeth, 100)",
344
+ " else",
345
+ " def_mat_fm(x0_iron_tooth, y0_iron_tooth, ur, 100)",
346
+ " end",
347
+ " end",
317
348
  'end\n']
318
349
  self.content.append('\n'.join(txt))
319
350
 
320
- txt = [u"if x0_shaft > 0.0 then",
321
- u" if mcvkey_shaft ~= 'dummy' then",
351
+ txt = ['if x0_shaft > 0.0 then',
352
+ " if mcvkey_shaft ~= 'dummy' then",
322
353
  ' def_mat_fm_nlin(x0_shaft, y0_shaft, "lightgrey", mcvkey_shaft, 100)',
323
354
  ' else',
324
355
  ' def_mat_fm(x0_shaft, y0_shaft, ur, 100)',
@@ -407,15 +438,15 @@ class FslRenderer(object):
407
438
  self.content.append('\nx0, y0 = {}, {}'. format(
408
439
  self.fm_nlin[0], self.fm_nlin[1]))
409
440
 
410
- mat = [u"if fm_nlin_mcvfile ~= 'dummy' then",
411
- u" if fm_nlin_mcvfile == 'air' then",
412
- u" def_mat_fm(x0,y0, 1.0, fm_nlin_rlen)",
413
- u" else",
414
- u" def_mat_fm_nlin(x0,y0, fm_nlin_colour, fm_nlin_mcvfile, fm_nlin_rlen)",
415
- u" end",
416
- u"else",
417
- u" def_mat_fm(x0,y0, 1000.0, fm_nlin_rlen)",
418
- u"end"]
441
+ mat = ["if fm_nlin_mcvfile ~= 'dummy' then",
442
+ " if fm_nlin_mcvfile == 'air' then",
443
+ " def_mat_fm(x0,y0, 1.0, fm_nlin_rlen)",
444
+ " else",
445
+ " def_mat_fm_nlin(x0,y0, fm_nlin_colour, fm_nlin_mcvfile, fm_nlin_rlen)",
446
+ " end",
447
+ "else",
448
+ " def_mat_fm(x0,y0, 1000.0, fm_nlin_rlen)",
449
+ "end"]
419
450
  self.content.append('\n'.join(mat))
420
451
 
421
452
  if self.shaft:
@@ -491,7 +522,6 @@ class FslRenderer(object):
491
522
  return self.content
492
523
 
493
524
  def render_main(self,
494
- motor,
495
525
  m_inner, m_outer,
496
526
  inner, outer,
497
527
  params):
@@ -511,6 +541,27 @@ class FslRenderer(object):
511
541
  m_outer.num_of_layers(),
512
542
  2)
513
543
  self.agndst = params.get('agndst', 0.1)
544
+ excwin = []
545
+ if self.mtype == 'EESM':
546
+ excwin = [
547
+ 'r,beta = c2pr(m.xcoil_r, m.ycoil_r)',
548
+ 'phi = math.pi/m.num_poles',
549
+ 'alpha = phi-beta',
550
+ 'm.num_wires = 1',
551
+ 'dir = {"wi", "wo"}',
552
+ 'xcoil, ycoil = pr2c(r, phi - alpha)',
553
+ 'def_new_wdg(xcoil, ycoil, "violet", "Exc", m.num_wires, 10.0, dir[1])',
554
+ 'xcoil, ycoil = pr2c(r, phi + alpha)',
555
+ 'add_to_wdg(xcoil, ycoil, wsamekey, dir[2], "wser")',
556
+ 'for i = 2, m.npols_gen do',
557
+ ' n = (i+1) % 2 + 1',
558
+ ' phi = phi + 2*math.pi/m.num_poles',
559
+ ' xcoil, ycoil = pr2c(r, phi - alpha)',
560
+ ' add_to_wdg(xcoil, ycoil, wsamekey, dir[n], "wser")',
561
+ ' xcoil, ycoil = pr2c(r, phi + alpha)',
562
+ ' n = i % 2 + 1',
563
+ ' add_to_wdg(xcoil, ycoil, wsamekey, dir[n], "wser")',
564
+ 'end']
514
565
  return [
515
566
  '-- generated from DXF by femagtools {}'.format(__version__),
516
567
  'exit_on_error = false',
@@ -598,4 +649,4 @@ class FslRenderer(object):
598
649
  ' pre_models("Gen_winding")',
599
650
  ' pre_models("gen_pocfile")',
600
651
  'end\n',
601
- 'save_model(cont)\n']
652
+ 'save_model(cont)\n'] + excwin
@@ -435,6 +435,14 @@ def points_on_arc(center, radius, startangle, endangle, parts=8):
435
435
  center[1] + radius * np.sin(alpha))
436
436
 
437
437
 
438
+ def points_on_line(p1, p2, parts=2):
439
+ x_dist = (p2[0] - p1[0]) / parts
440
+ y_dist = (p2[1] - p1[1]) / parts
441
+ x, y = p1
442
+ for i in range(1, parts):
443
+ yield (x + i*x_dist, y + i*y_dist)
444
+
445
+
438
446
  class Timer(object):
439
447
  def __init__(self, start_it=False):
440
448
  self.starttime = None
femagtools/dxfsl/geom.py CHANGED
@@ -34,7 +34,7 @@ from .functions import middle_point_of_line, middle_point_of_arc
34
34
  from .functions import middle_angle, positive_angle
35
35
  from .functions import normalise_angle, is_same_angle
36
36
  from .functions import part_of_circle, gcd
37
- from .functions import point_on_arc, nodes_are_equal
37
+ from .functions import point_on_arc, points_on_line, nodes_are_equal
38
38
  from .functions import area_size
39
39
  import io
40
40
  import time
@@ -749,6 +749,38 @@ class Geometry(object):
749
749
  rtol=self.rtol,
750
750
  atol=self.atol)
751
751
 
752
+ def split_all_lines_longer_than(self, length):
753
+ """split lines longer than length"""
754
+ new_lines = []
755
+ rem_lines = []
756
+ elist = self.elements_and_nodes(Line)
757
+
758
+ for p1, p2, line in elist:
759
+ line_len = line.length()
760
+ if line_len < length:
761
+ continue
762
+ d = abs(distance(self.center, p1) - distance(self.center, p2))
763
+ parts = 3
764
+ if d > line_len / 2:
765
+ parts = 5
766
+ elif d > line_len / 3:
767
+ parts = 4
768
+ p_start = p1
769
+
770
+ for p_next in points_on_line(p1, p2, parts=parts):
771
+ new_lines.append(Line(Element(start=p_start, end=p_next)))
772
+ p_start = p_next
773
+
774
+ new_lines.append(Line(Element(start=p_start, end=p2)))
775
+ rem_lines.append((p1, p2))
776
+
777
+ for p1, p2 in rem_lines:
778
+ self._remove_edge(p1, p2)
779
+ for new_line in new_lines:
780
+ self.add_element(new_line,
781
+ rtol=self.rtol,
782
+ atol=self.atol)
783
+
752
784
  def circles(self):
753
785
  """return list of circle nodes"""
754
786
  return [n[1]['object'] for n in self.g.nodes(data=True)
@@ -3040,11 +3072,20 @@ class Geometry(object):
3040
3072
  for e in elist:
3041
3073
  e.init_attributes('lightblue', 'no_fsl')
3042
3074
 
3043
- def search_subregions(self, startangle, endangle, single=False):
3075
+ def search_subregions(self, startangle, endangle, EESM, single=False):
3044
3076
  if self.is_stator():
3045
- self.search_stator_subregions(startangle, endangle, single=single)
3077
+ self.search_stator_subregions(startangle,
3078
+ endangle,
3079
+ single=single)
3046
3080
  elif self.is_rotor():
3047
- self.search_rotor_subregions(startangle, endangle, single=single)
3081
+ if EESM:
3082
+ self.search_EESM_rotor_subregions(startangle,
3083
+ endangle,
3084
+ single=single)
3085
+ else:
3086
+ self.search_PMSM_rotor_subregions(startangle,
3087
+ endangle,
3088
+ single=single)
3048
3089
  else:
3049
3090
  logger.warning("no stator or rotor assigned")
3050
3091
  self.search_unknown_subregions()
@@ -3262,25 +3303,88 @@ class Geometry(object):
3262
3303
  self.check_shaft_area(shaft_areas[0])
3263
3304
  logger.debug("End of search_stator_subregions")
3264
3305
 
3265
- def search_rotor_subregions(self,
3266
- startangle,
3267
- endangle,
3268
- single=False):
3269
- logger.debug("Begin of search_rotor_subregions")
3306
+ def search_EESM_rotor_subregions(self,
3307
+ startangle,
3308
+ endangle,
3309
+ single=False):
3310
+ logger.debug("Begin of search_EESM_rotor_subregions")
3311
+
3312
+ if self.alfa == 0.0:
3313
+ self.alfa = np.pi * 2.0
3314
+
3315
+ types = {}
3316
+ for area in self.list_of_areas():
3317
+ t = area.mark_EESM_rotor_subregions(self.is_inner,
3318
+ self.is_mirrored(),
3319
+ self.alfa,
3320
+ self.center,
3321
+ self.min_radius,
3322
+ self.max_radius,
3323
+ startangle,
3324
+ endangle)
3325
+ if t in types:
3326
+ types[t] += 1
3327
+ else:
3328
+ types[t] = 1
3329
+
3330
+ windings = [a for a in self.list_of_areas()
3331
+ if a.is_type(AREA.TYPE_WINDINGS_OR_IRON)]
3332
+
3333
+ if self.is_mirrored():
3334
+ [a.set_type(AREA.TYPE_IRON) for a in windings
3335
+ if a.close_to_endangle]
3336
+ wlist = [(a.max_angle, a) for a in self.list_of_areas()
3337
+ if a.is_type(AREA.TYPE_WINDINGS_OR_IRON)]
3338
+ if wlist:
3339
+ wlist.sort(reverse=True)
3340
+ a, w = wlist[0]
3341
+ w.set_type(AREA.TYPE_FD_WINDINGS)
3342
+ else:
3343
+ midangle = middle_angle(startangle, endangle)
3344
+ [a.set_type(AREA.TYPE_IRON) for a in windings
3345
+ if a.max_angle > midangle and a.min_angle < midangle]
3346
+ windings = [a for a in self.list_of_areas()
3347
+ if a.is_type(AREA.TYPE_WINDINGS_OR_IRON)]
3348
+ if len(windings) > 1:
3349
+ wlist = []
3350
+ for w in windings:
3351
+ if w.max_angle < midangle:
3352
+ angle = alpha_angle(w.max_angle, midangle)
3353
+ else:
3354
+ angle = alpha_angle(midangle, w.min_angle)
3355
+ wlist.append((angle, w))
3356
+ wlist.sort()
3357
+ a1, w1 = wlist[0]
3358
+ a2, w2 = wlist[1]
3359
+ if np.isclose(a1, a2):
3360
+ w1.set_type(AREA.TYPE_FD_WINDINGS)
3361
+ w2.set_type(AREA.TYPE_FD_WINDINGS)
3362
+
3363
+ # all remaining areas are in iron
3364
+ [a.set_type(AREA.TYPE_IRON) for a in self.list_of_areas()
3365
+ if a.is_type(AREA.TYPE_WINDINGS_OR_IRON)]
3366
+
3367
+ logger.debug("End of search_EESM_rotor_subregions")
3368
+
3369
+ def search_PMSM_rotor_subregions(self,
3370
+ startangle,
3371
+ endangle,
3372
+ single=False):
3373
+ logger.debug("Begin of search_PMSM_rotor_subregions")
3270
3374
 
3271
3375
  if self.alfa == 0.0:
3272
3376
  self.alfa = np.pi * 2.0
3273
3377
 
3274
3378
  types = {}
3275
3379
  for area in self.list_of_areas():
3276
- t = area.mark_rotor_subregions(self.is_inner,
3277
- self.is_mirrored(),
3278
- self.alfa,
3279
- self.center,
3280
- self.min_radius,
3281
- self.max_radius,
3282
- startangle,
3283
- endangle)
3380
+ t = area.mark_PMSM_rotor_subregions(self.is_inner,
3381
+ self.is_mirrored(),
3382
+ self.alfa,
3383
+ self.center,
3384
+ self.min_radius,
3385
+ self.max_radius,
3386
+ startangle,
3387
+ endangle)
3284
3388
  if t in types:
3285
3389
  types[t] += 1
3286
3390
  else:
@@ -3408,7 +3512,7 @@ class Geometry(object):
3408
3512
  self.search_stator_subregions(startangle, endangle, single=single)
3409
3513
  return
3410
3514
 
3411
- logger.debug("end of search_rotor_subregions")
3515
+ logger.debug("end of search_PMSM_rotor_subregions")
3412
3516
 
3413
3517
  def recalculate_magnet_orientation(self):
3414
3518
  logger.debug("begin of recalculate_magnet_orientation")
@@ -3502,6 +3606,10 @@ class Geometry(object):
3502
3606
  return len([area for area in self.list_of_areas()
3503
3607
  if area.is_type(type)])
3504
3608
 
3609
+ def area_size_of_type(self, type):
3610
+ return sum([area.surface for area in self.list_of_areas()
3611
+ if area.is_type(type)])*1e-3
3612
+
3505
3613
  def num_of_windings(self):
3506
3614
  return self.num_areas_of_type(AREA.TYPE_WINDINGS)
3507
3615
 
@@ -590,6 +590,10 @@ class Machine(object):
590
590
  return w*2
591
591
  return w
592
592
 
593
+ def slot_area(self):
594
+ from .area import TYPE_WINDINGS
595
+ return self.geom.area_size_of_type(TYPE_WINDINGS)
596
+
593
597
  def find_symmetry(self, sym_tolerance, is_inner, is_outer, plt):
594
598
  logger.debug("begin of find_symmetry")
595
599
  if self.radius <= 0.0:
@@ -1046,21 +1050,36 @@ class Machine(object):
1046
1050
  cp_machine.geom.sym_counterpart = self.get_symmetry_part()
1047
1051
  cp_machine.geom.sym_part = cp_machine.get_symmetry_part()
1048
1052
 
1049
- def search_subregions(self, single=False):
1053
+ def search_subregions(self, EESM, single=False):
1050
1054
  logger.debug("Search subregions")
1051
- self.geom.search_subregions(self.startangle, self.endangle, single=single)
1052
-
1053
- def search_rotor_subregions(self, single=False):
1054
- self.geom.search_rotor_subregions(self.startangle, self.endangle, single=single)
1055
+ self.geom.search_subregions(self.startangle,
1056
+ self.endangle,
1057
+ EESM,
1058
+ single=single)
1059
+
1060
+ def search_rotor_subregions(self, EESM, single=False):
1061
+ if EESM:
1062
+ self.geom.search_EESM_rotor_subregions(self.startangle,
1063
+ self.endangle,
1064
+ single=single)
1065
+ else:
1066
+ self.geom.search_PMSM_rotor_subregions(self.startangle,
1067
+ self.endangle,
1068
+ single=single)
1055
1069
 
1056
1070
  def search_stator_subregions(self, single=False):
1057
- self.geom.search_stator_subregions(self.startangle, self.endangle, single=single)
1071
+ self.geom.search_stator_subregions(self.startangle,
1072
+ self.endangle,
1073
+ single=single)
1058
1074
 
1059
- def rebuild_subregions(self, single=False):
1075
+ def rebuild_subregions(self, EESM, single=False):
1060
1076
  logger.debug("Rebuild subregions")
1061
1077
  self.geom.set_edge_attributes()
1062
1078
  self.geom.area_list = []
1063
- self.geom.search_subregions(self.startangle, self.endangle, single=single)
1079
+ self.geom.search_subregions(self.startangle,
1080
+ self.endangle,
1081
+ EESM,
1082
+ single=single)
1064
1083
 
1065
1084
  def has_windings(self):
1066
1085
  return self.geom.has_windings
@@ -1170,7 +1189,9 @@ class Machine(object):
1170
1189
  self.geom.area_list = []
1171
1190
  logger.debug("create subregions again")
1172
1191
  self.geom.create_list_of_areas()
1173
- self.geom.search_subregions(self.startangle, self.endangle)
1192
+ self.geom.search_subregions(self.startangle,
1193
+ self.endangle,
1194
+ False)
1174
1195
 
1175
1196
  logger.debug("end create_mirror_lines_outside_windings")
1176
1197
 
femagtools/femag.py CHANGED
@@ -366,9 +366,9 @@ class BaseFemag(object):
366
366
  with open(os.path.join(self.workdir, 'FEMAG-FSL.log')) as f:
367
367
  for l in f:
368
368
  if l.startswith('New model') or l.startswith('Load model'):
369
- model = l.split('"')[1]
370
- break
371
- return model
369
+ return l.split('"')[1]
370
+
371
+ raise ValueError(f"Model not found in {self.workdir}/'FEMAG-FSL.log'")
372
372
 
373
373
  def readResult(self, simulation, bch=None):
374
374
  if simulation: