femagtools 1.3.0__py3-none-any.whl → 1.3.2__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 (47) hide show
  1. femagtools/__init__.py +1 -1
  2. femagtools/airgap.py +11 -37
  3. femagtools/amela.py +148 -13
  4. femagtools/bch.py +19 -3
  5. femagtools/dxfsl/area.py +68 -15
  6. femagtools/dxfsl/converter.py +15 -6
  7. femagtools/dxfsl/fslrenderer.py +13 -8
  8. femagtools/dxfsl/functions.py +1 -1
  9. femagtools/dxfsl/geom.py +415 -62
  10. femagtools/dxfsl/machine.py +97 -5
  11. femagtools/dxfsl/shape.py +46 -2
  12. femagtools/ecloss.py +393 -0
  13. femagtools/femag.py +25 -1
  14. femagtools/fsl.py +3 -2
  15. femagtools/hxy.py +126 -0
  16. femagtools/isa7.py +37 -24
  17. femagtools/machine/__init__.py +14 -13
  18. femagtools/machine/effloss.py +153 -32
  19. femagtools/machine/im.py +137 -56
  20. femagtools/machine/pm.py +584 -202
  21. femagtools/machine/sm.py +218 -64
  22. femagtools/machine/utils.py +12 -8
  23. femagtools/mcv.py +6 -8
  24. femagtools/model.py +11 -1
  25. femagtools/parstudy.py +1 -1
  26. femagtools/plot.py +159 -35
  27. femagtools/templates/afm_rotor.mako +102 -0
  28. femagtools/templates/afm_stator.mako +141 -0
  29. femagtools/templates/airgapinduc.mako +3 -3
  30. femagtools/templates/basic_modpar.mako +23 -2
  31. femagtools/templates/cogg_calc.mako +28 -5
  32. femagtools/templates/cu_losses.mako +1 -1
  33. femagtools/templates/fieldcalc.mako +39 -0
  34. femagtools/templates/gen_winding.mako +52 -47
  35. femagtools/templates/mesh-airgap.mako +43 -0
  36. femagtools/templates/stator3Linear.mako +5 -4
  37. femagtools/templates/therm-dynamic.mako +12 -6
  38. femagtools/templates/therm-static.mako +12 -0
  39. femagtools/templates/torq_calc.mako +2 -4
  40. femagtools/utils.py +45 -0
  41. femagtools/windings.py +2 -1
  42. {femagtools-1.3.0.dist-info → femagtools-1.3.2.dist-info}/METADATA +1 -1
  43. {femagtools-1.3.0.dist-info → femagtools-1.3.2.dist-info}/RECORD +47 -41
  44. {femagtools-1.3.0.dist-info → femagtools-1.3.2.dist-info}/WHEEL +1 -1
  45. {femagtools-1.3.0.dist-info → femagtools-1.3.2.dist-info}/LICENSE +0 -0
  46. {femagtools-1.3.0.dist-info → femagtools-1.3.2.dist-info}/entry_points.txt +0 -0
  47. {femagtools-1.3.0.dist-info → femagtools-1.3.2.dist-info}/top_level.txt +0 -0
femagtools/__init__.py CHANGED
@@ -9,7 +9,7 @@
9
9
 
10
10
  """
11
11
  __title__ = 'femagtools'
12
- __version__ = '1.3.0'
12
+ __version__ = '1.3.2'
13
13
  __author__ = 'Ronald Tanner'
14
14
  __license__ = 'BSD'
15
15
  __copyright__ = 'Copyright 2016-2022 SEMAFOR Informatik & Energie AG'
femagtools/airgap.py CHANGED
@@ -9,6 +9,7 @@
9
9
  """
10
10
  import numpy as np
11
11
  import logging
12
+ from . import utils
12
13
 
13
14
  logger = logging.getLogger(__name__)
14
15
 
@@ -22,49 +23,22 @@ def fft(pos, b, pmod=0):
22
23
  b: (list of floats) flux density values
23
24
  pmod: number of poles in model (ignored if 0)
24
25
  """
25
- model_angle = pos[-1] - pos[0]
26
- ntiles = int(round(360/model_angle))
27
-
28
- if pmod:
29
- negative_periodic = pmod % 2
30
- else:
31
- negative_periodic = np.abs(b[0] - b[-1])/np.max(b) > 1
32
-
33
- if negative_periodic:
34
- bx = np.append(
35
- np.concatenate(
36
- [n*b[:-1]
37
- for n in [m % 2 or -1
38
- for m in range(1, ntiles+1)]]),
39
- b[0])
40
- else:
41
- bx = np.append(
42
- np.tile(b[:-1], ntiles),
43
- b[0])
44
-
45
- N = len(bx)
46
- # compute DFT from induction
47
- Y = np.fft.fft(bx)
48
-
49
- # find the peak (amplitude of base harmonic)
50
- i = np.argmax(np.abs(Y[:N//2]))
51
- a = 2*np.abs(Y[i])/N
52
- freq = np.fft.fftfreq(N, d=pos[1]-pos[0])
53
- T0 = np.abs(1/freq[i])
26
+ r = utils.fft(pos, b, pmod)
27
+ Bamp = r['a']
28
+ alfa0 = r['alfa0']
29
+ T0 = r['T0']
54
30
  npoles = 2*int(np.ceil(360/T0))
55
31
  logger.info("flux density: %s poles B amp %f ",
56
- npoles, a)
57
-
58
- alfa0 = np.angle(Y[i])
59
- return dict(Bamp=a, npoles=npoles,
32
+ npoles, r['a'])
33
+ return dict(Bamp=Bamp, npoles=npoles,
60
34
  phi0=alfa0,
61
35
  pos=pos.tolist(),
62
36
  B=b.tolist(),
63
37
  nue=np.arange(0, 9*npoles).tolist(),
64
- B_nue=(2*np.abs(Y[:9*npoles])/N).tolist(),
65
- B_fft=(a*np.cos(2*np.pi*pos/T0+alfa0)).tolist(),
66
- Bi=bx.tolist(),
67
- phi=np.linspace(pos[0], 360+pos[0], len(bx)).tolist())
38
+ B_nue=r['nue'],
39
+ B_fft=(Bamp*np.cos(2*np.pi*pos/T0+alfa0)).tolist(),
40
+ Bi=r['yi'],
41
+ phi=np.linspace(pos[0], 360+pos[0], len(r['yi'])).tolist())
68
42
 
69
43
 
70
44
  def read(filename, pmod=0):
femagtools/amela.py CHANGED
@@ -11,12 +11,110 @@ import logging
11
11
  from pathlib import Path
12
12
  import femagtools.nc
13
13
  import numpy as np
14
- from numpy import pi
14
+ from numpy import pi, sin, cos
15
15
  import subprocess
16
16
 
17
17
  # set logging
18
18
  logger = logging.getLogger(__name__)
19
19
 
20
+ def geometry_id(bndx, bndy):
21
+ '''identify the magnet geometry'''
22
+ # caculate magnet area
23
+ xy = 0
24
+ yx = 0
25
+ for i in range(len(bndy)):
26
+ if i < (len(bndy)-1):
27
+ xy += bndx[i]*bndy[i+1]
28
+ yx += bndy[i]*bndx[i+1]
29
+ else:
30
+ xy += bndx[i]*bndy[0]
31
+ yx += bndy[i]*bndx[0]
32
+ area = np.abs(yx-xy)*0.5
33
+
34
+ x0, y0 = np.mean(bndx), np.mean(bndy)
35
+ distances = []
36
+ for i in range(len(bndx)):
37
+ for j in range(len(bndy)):
38
+ dist = np.sqrt((bndx[i] - bndx[j])**2 + (bndy[i] - bndy[j])**2)
39
+ distances.append([dist, bndx[i], bndx[j], bndy[i], bndy[j]])
40
+
41
+ distances.sort(reverse=True)
42
+ xe = [distances[0][2], distances[2][1], distances[0][1], distances[2][2]]
43
+ ye = [distances[0][4], distances[2][3], distances[0][3], distances[2][4]]
44
+
45
+ # dimension
46
+ dim = np.zeros((3, 5))
47
+ x1, y1 = xe[0], ye[0]
48
+
49
+ for i in range(3):
50
+ x2, y2 = xe[i+1], ye[i+1]
51
+ dim[i, 0] = np.sqrt((x2-x1)**2 + (y2-y1)**2)
52
+ dim[i, 1:3] = [x1, x2]
53
+ dim[i, 3:5] = [y1, y2]
54
+
55
+ dim = dim[np.lexsort((dim[:, 2], dim[:, 1], dim[:, 0]))]
56
+ dx12, dy12 = dim[1, 1] - dim[1, 2], dim[1, 3] - dim[1, 4]
57
+ dx14, dy14 = dim[0, 1] - dim[0, 2], dim[0, 3] - dim[0, 4]
58
+
59
+ alp1 = np.arctan2(dy12, dx12)
60
+ alp2 = np.arctan2(dy14, dx14)
61
+
62
+ if alp1 < 0: alp1 += 2*np.pi
63
+ if alp2 < 0: alp2 += 2*np.pi
64
+ if alp2 < alp1:
65
+ alp2 += np.pi
66
+ alpha = (alp1 + (alp2 - np.pi/2))/2
67
+ else:
68
+ alpha = (alp1 + (alp2 - np.pi/2))/2 + np.pi
69
+
70
+ wm = dim[1, 0]
71
+ hm = area/wm
72
+
73
+ return dict(wm=wm,
74
+ hm=hm,
75
+ x0=x0,
76
+ y0=y0,
77
+ area=area,
78
+ alpha=alpha)
79
+
80
+ def tf(b1, b2, alpha):
81
+ '''Tranformation Matrix'''
82
+ T = np.array([[cos(alpha), sin(alpha)],
83
+ [-sin(alpha), cos(alpha)]])
84
+ if b1.ndim > 1:
85
+ r = T.dot(((b1.ravel()), (b2.ravel())))
86
+ return [r[0, :].reshape(*b1.shape),
87
+ r[1, :].reshape(*b1.shape)]
88
+ else:
89
+ return T.dot(((b1), (b2)))
90
+
91
+ def transform_coord(geometry, xcp, ycp):
92
+ '''transform from global coord to local coord'''
93
+ # transformation
94
+ elcp = tf(b1=np.array(xcp)-geometry['x0'],
95
+ b2=np.array(ycp)-geometry['y0'],
96
+ alpha=geometry['alpha'])
97
+ return dict(excpl=elcp[0, :]+geometry['wm']/2,
98
+ eycpl=elcp[1, :]+geometry['hm']/2,
99
+ excp=np.array(xcp),
100
+ eycp=np.array(ycp))
101
+
102
+ def transform_flux_denstiy(geometry, bx, by):
103
+ '''transform the magnet flux density to local coordinate system'''
104
+ # transformation
105
+ bxy = tf(b1=bx,
106
+ b2=by,
107
+ alpha=geometry['alpha'])
108
+
109
+ # remove DC component
110
+ bxf = np.mean(bxy[0].T - np.mean(bxy[0],axis=1).T,axis=1)
111
+ byf = np.mean(bxy[1].T - np.mean(bxy[1],axis=1).T,axis=1)
112
+
113
+ return dict(bxl=bxy[0],
114
+ byl=bxy[1],
115
+ bxf=bxf,
116
+ byf=byf
117
+ )
20
118
 
21
119
  class Amela():
22
120
  '''Run Amela Calculation
@@ -66,7 +164,7 @@ class Amela():
66
164
  if 'nseglen' in self.magn:
67
165
  self.cmd.append(f"--nseglen {self.magn['nseglen']}")
68
166
 
69
- def get_magnet_data(self):
167
+ def get_magnet_data(self, ibeta=None):
70
168
  '''Extract magnet data from nc file
71
169
  Parameters
72
170
  ----------
@@ -92,7 +190,15 @@ class Amela():
92
190
  ycp = [[] for i in range(len(spel_key))]
93
191
  bndx = [[] for i in range(len(spel_key))]
94
192
  bndy = [[] for i in range(len(spel_key))]
95
-
193
+ # prepare data for ialh method
194
+ wm = []
195
+ hm = []
196
+ alpha = []
197
+ x0 = []
198
+ y0 = []
199
+ geometry = []
200
+ elcp = []
201
+ bl = []
96
202
  # conductivity and permeability of the magnets
97
203
  cond = 0
98
204
  mur = 0
@@ -124,15 +230,26 @@ class Amela():
124
230
  bndkey[k].pop(-1)
125
231
  bndx[k].pop(-1)
126
232
  bndy[k].pop(-1)
233
+ geo = geometry_id(bndx=bndx[k], bndy=bndy[k])
234
+ geometry.append(geo)
235
+ # necessary?
236
+ hm.append(geo['hm'])
237
+ wm.append(geo['wm'])
238
+ x0.append(geo['x0'])
239
+ y0.append(geo['y0'])
240
+ alpha.append(geo['alpha'])
127
241
 
128
242
  # default load angle (input beta I vs Up)
129
- num_cases = r.el_fe_induction_1.shape[3] - 1
130
- if 'loadcase' in self.magn:
131
- indx = self.magn['loadcase'] - 1
243
+ if ibeta is not None:
244
+ indx = ibeta
132
245
  else:
133
- indx = num_cases
134
- if indx == 3:
135
- indx = num_cases # avoid error
246
+ num_cases = r.el_fe_induction_1.shape[3] - 1
247
+ if 'loadcase' in self.magn:
248
+ indx = self.magn['loadcase'] - 1
249
+ else:
250
+ indx = num_cases
251
+ if indx == 3:
252
+ indx = num_cases # avoid error
136
253
 
137
254
  # stationary case, no rotation
138
255
  poles = 0
@@ -159,6 +276,10 @@ class Amela():
159
276
  by[i][0][index, :] = fd['bx']*np.sin(theta) + \
160
277
  fd['by']*np.cos(theta)
161
278
 
279
+ elcp.append(transform_coord(geometry[i], xcp[i], ycp[i]))
280
+ bl.append(transform_flux_denstiy(geometry[i], bx[i][0], by[i][0]))
281
+
282
+
162
283
  if poles == 0:
163
284
  freq = self.magn.get('f', r.speed)
164
285
  time_vec = np.linspace(0, 1/freq, len(r.pos_el_fe_induction))
@@ -177,9 +298,10 @@ class Amela():
177
298
  pm_data = []
178
299
  for i in range(len(spel_key)):
179
300
  pm_data.append(dict(name='pm_data_se' + str(spel_key[i]),
180
- hm=self.magn.get('hm', 0),
181
- wm=self.magn.get('wm', 0),
301
+ hm=self.magn.get('hm', hm[i]),
302
+ wm=self.magn.get('wm', wm[i]),
182
303
  lm=self.magn.get('lm', r.arm_length*1e3),
304
+ alpha=alpha[i],
183
305
  ls=r.arm_length*1e3,
184
306
  sigma=float(self.magn.get('sigma', cond)),
185
307
  mur=float(self.magn.get('mur', mur)),
@@ -190,7 +312,10 @@ class Amela():
190
312
  bndkeys=bndkey[i],
191
313
  bndx=[float(c) for c in bndx[i]],
192
314
  bndy=[float(c) for c in bndy[i]],
193
- area=spel_area[i]))
315
+ bl=bl[i],
316
+ elcp=elcp[i],
317
+ area=spel_area[i],
318
+ spel_key=spel_key[i]))
194
319
  pm_data[i].update(pos)
195
320
 
196
321
  for k in range(len(pm_node_key)):
@@ -215,6 +340,14 @@ class Amela():
215
340
  else:
216
341
  return [pm_data[0]]
217
342
 
343
+ def get_magnet_data_all(self, num_op):
344
+ '''get all magnet data for all loadcases'''
345
+ pm_data = []
346
+ for i in num_op:
347
+ pmd = self.get_magnet_data(ibeta=i)
348
+ pm_data.append(pmd)
349
+ return pm_data
350
+
218
351
  def export_json(self, pm_data):
219
352
  '''Export magnet data to json files
220
353
  Parameters
@@ -230,6 +363,9 @@ class Amela():
230
363
  for i in pm_data:
231
364
  filename = (pm_dir / i['name']).with_suffix('.json')
232
365
  self.jsonfile.append(str(filename)) # for the future use
366
+ # pop out non necessary data
367
+ i.pop('bl')
368
+ i.pop('elcp')
233
369
  with filename.open('w') as f:
234
370
  json.dump(i, f)
235
371
  logger.info('Exporting %s ...', i['name'])
@@ -279,4 +415,3 @@ class Amela():
279
415
  with log_file.open('w') as output:
280
416
  subprocess.run(cmd, stdout=output)
281
417
  return self.read_loss(r)
282
-
femagtools/bch.py CHANGED
@@ -170,6 +170,7 @@ class Reader:
170
170
  self.dqPar = {}
171
171
  self.ldq = {}
172
172
  self.losses = []
173
+ self.magnet_loss_th = []
173
174
  self.demag = []
174
175
  self.weights = []
175
176
  self.weight = {}
@@ -1497,11 +1498,12 @@ class Reader:
1497
1498
  if l.find('Fe-Losses-Rotor') > -1:
1498
1499
  rec = self.__findNums(content[i+3])
1499
1500
  if len(rec) == 2:
1500
- if content[i+1].find('Iron') > -1 and content[i+1].find('StJo') > 0:
1501
+ if (content[i+1].find('Iron') > -1 and content[i+1].find('StJo') > 0 or
1502
+ content[i+1].split() == ['RoZa', 'RoJo']):
1501
1503
  self.external_rotor = True
1502
1504
  # TODO: there might be better places to check this
1503
- losses['stajo'] = floatnan(rec[0])
1504
- losses['staza'] = floatnan(rec[1])
1505
+ losses['staza'] = floatnan(rec[0])
1506
+ losses['stajo'] = floatnan(rec[1])
1505
1507
  losses['total'] += losses['staza']+losses['stajo']
1506
1508
  else:
1507
1509
  losses['rotfe'] = floatnan(rec[1])
@@ -1509,6 +1511,20 @@ class Reader:
1509
1511
  i += 4
1510
1512
  continue
1511
1513
 
1514
+ if l.find('Fe-Losses-Stator') > -1:
1515
+ rec = self.__findNums(content[i+3])
1516
+ if len(rec) == 2:
1517
+ if content[i+1].split() == ['StJo', 'StZa']:
1518
+ losses['stajo'] = floatnan(rec[0])
1519
+ losses['staza'] = floatnan(rec[1])
1520
+ losses['total'] += losses['staza']+losses['stajo']
1521
+
1522
+ if content[i+1].split() == ['rotf', '----']:
1523
+ losses['rotfe'] = sum([floatnan(x) for x in rec])
1524
+ losses['total'] += losses['rotfe']
1525
+ i += 4
1526
+ continue
1527
+
1512
1528
  if l.find('Magnet-Losses') > -1:
1513
1529
  rec = self.__findNums(content[i+1])
1514
1530
  if len(rec) == 1:
femagtools/dxfsl/area.py CHANGED
@@ -39,6 +39,8 @@ class Area(object):
39
39
  self.min_air_angle = 0.0
40
40
  self.max_air_angle = 0.0
41
41
  self.close_to_ag = False
42
+ self.close_to_ag_startcorner = False
43
+ self.close_to_ag_endcorner = False
42
44
  self.close_to_startangle = False
43
45
  self.close_to_endangle = False
44
46
  self.mag_rectangle = False
@@ -128,6 +130,18 @@ class Area(object):
128
130
  except Exception as e:
129
131
  return
130
132
 
133
+ def has_fsl(self):
134
+ try:
135
+ return self.fsl
136
+ except AttributeError:
137
+ return True
138
+
139
+ def list_of_equal_edges(self, a):
140
+ for e1 in self.area:
141
+ for e2 in a.area:
142
+ if e1.n1 == e2.n1 and e1.n2 == e2.n2:
143
+ yield e1
144
+
131
145
  def virtual_nodes(self, render=False):
132
146
  if len(self.area) < 2:
133
147
  return
@@ -1044,6 +1058,12 @@ class Area(object):
1044
1058
  return True
1045
1059
  return False
1046
1060
 
1061
+ def is_touching_areas(self, areas):
1062
+ for a in areas:
1063
+ if self.is_touching(a):
1064
+ return True
1065
+ return False
1066
+
1047
1067
  def mark_stator_subregions(self,
1048
1068
  is_inner,
1049
1069
  stator_size,
@@ -1143,18 +1163,37 @@ class Area(object):
1143
1163
  logger.debug("***** air (part of a circle)\n")
1144
1164
  return self.type
1145
1165
 
1166
+ def bad_winding_position():
1167
+ if is_inner:
1168
+ radius_third = airgap_radius - (airgap_radius - opposite_radius) * 0.33
1169
+ if self.max_dist < radius_third:
1170
+ return True
1171
+ else: # outer
1172
+ radius_third = airgap_radius + (opposite_radius - airgap_radius) * 0.33
1173
+ if self.min_dist > radius_third:
1174
+ return True
1175
+ return False
1176
+
1146
1177
  if self.min_angle > 0.001:
1147
1178
  if self.max_angle < alpha - 0.001:
1148
- self.type = 2 # windings
1149
- logger.debug("***** windings #1\n")
1179
+ if bad_winding_position():
1180
+ self.type = 12 # windings or air
1181
+ logger.debug("***** windings or air #1\n")
1182
+ else:
1183
+ self.type = 2 # windings
1184
+ logger.debug("***** windings #1\n")
1150
1185
  return self.type
1151
1186
  if mirrored:
1152
- self.type = 2 # windings
1153
- logger.debug("***** windings #2\n")
1187
+ if bad_winding_position():
1188
+ self.type = 12 # windings or air
1189
+ logger.debug("***** windings or air #2\n")
1190
+ else:
1191
+ self.type = 2 # windings
1192
+ logger.debug("***** windings #2\n")
1154
1193
  return self.type
1155
1194
 
1156
1195
  self.type = 0 # air
1157
- logger.debug("***** air #2")
1196
+ logger.debug("***** air #3")
1158
1197
 
1159
1198
  if self.close_to_startangle or self.close_to_endangle:
1160
1199
  f = self.surface / stator_size
@@ -1167,7 +1206,7 @@ class Area(object):
1167
1206
  logger.debug("***** air or iron close to border\n")
1168
1207
  return self.type
1169
1208
 
1170
- logger.debug("***** air #3\n")
1209
+ logger.debug("***** air #4\n")
1171
1210
  return 0
1172
1211
 
1173
1212
  def mark_rotor_subregions(self, is_inner, mirrored, alpha,
@@ -1319,6 +1358,15 @@ class Area(object):
1319
1358
  logger.debug(">>> air remains")
1320
1359
  return self.type
1321
1360
 
1361
+ def mark_airgap_corners(self, start_cp, end_cp):
1362
+ for n in self.list_of_nodes():
1363
+ if self.close_to_startangle:
1364
+ if points_are_close(n, start_cp):
1365
+ self.close_to_ag_startcorner = True
1366
+ if self.close_to_endangle:
1367
+ if points_are_close(n, end_cp):
1368
+ self.close_to_ag_endcorner = True
1369
+
1322
1370
  def area_size(self):
1323
1371
  nodes = [n for n in self.list_of_nodes()]
1324
1372
  return area_size(nodes)
@@ -1455,14 +1503,19 @@ class Area(object):
1455
1503
 
1456
1504
  def __str__(self):
1457
1505
  return "Area {}\n".format(self.id) + \
1458
- "distance: from {} to {}\n".\
1506
+ "distance...............: from {} to {}\n".\
1459
1507
  format(round(self.min_dist, 4), round(self.max_dist, 4)) + \
1460
- "height..: {}\n".format(self.height) + \
1461
- "alpha...: {}\n".format(self.alpha) + \
1462
- "angle...: from {} to {}\n".\
1508
+ "height.................: {}\n".format(self.height) + \
1509
+ "alpha..................: {}\n".format(self.alpha) + \
1510
+ "angle..................: from {} to {}\n".\
1463
1511
  format(round(self.min_angle, 6), round(self.max_angle, 6)) + \
1464
- "delta...: {}\n".format(self.delta) + \
1465
- "number..: {}\n".format(self.count) + \
1466
- "equal...: {}\n".format(len(self.equal_areas)) + \
1467
- "symmetry: {}\n".format(self.symmetry) + \
1468
- "sym_type: {}".format(self.sym_type)
1512
+ "delta..................: {}\n".format(self.delta) + \
1513
+ "number.................: {}\n".format(self.count) + \
1514
+ "equal areas............: {}\n".format(len(self.equal_areas)) + \
1515
+ "symmetry...............: {}\n".format(self.symmetry) + \
1516
+ "symmetry type..........: {}\n".format(self.sym_type) + \
1517
+ "close to airgap........: {}\n".format(self.close_to_ag) + \
1518
+ "close to startangle....: {}\n".format(self.close_to_startangle) + \
1519
+ "close to endangle......: {}\n".format(self.close_to_endangle) + \
1520
+ "close to ag startcorner: {}\n".format(self.close_to_ag_startcorner) + \
1521
+ "close to ag endcorner..: {}\n".format(self.close_to_ag_endcorner)
@@ -240,6 +240,7 @@ def convert(dxfile,
240
240
  cols=2, # columns
241
241
  num=3) # start num
242
242
  machine_inner.set_inner()
243
+ machine_inner.check_and_correct_geom("Inner")
243
244
 
244
245
  machine_outer = machine.copy(0.0, 2*np.pi, True, False)
245
246
  machine_outer = symmetry_search(machine_outer,
@@ -251,6 +252,7 @@ def convert(dxfile,
251
252
  rows=3, # rows
252
253
  cols=2, # columns
253
254
  num=4) # start num
255
+ machine_outer.check_and_correct_geom("Outer")
254
256
 
255
257
  machine_inner.sync_with_counterpart(machine_outer)
256
258
 
@@ -273,22 +275,25 @@ def convert(dxfile,
273
275
 
274
276
  machine_inner.delete_tiny_elements(mindist)
275
277
  machine_outer.delete_tiny_elements(mindist)
278
+ machine_inner.geom.create_corner_areas()
276
279
  logger.info("END of work: %s", basename)
277
280
 
278
281
  if show_plots:
279
282
  p.render_elements(machine_inner.geom, Shape,
280
283
  draw_inside=True, title=inner_name,
281
284
  rows=3, cols=2, num=5, show=False,
282
- # with_nodes=True,
283
- # neighbors=True,
285
+ with_corners=False,
286
+ with_nodes=False,
287
+ neighbors=False,
284
288
  write_id=write_id,
285
289
  fill_areas=True)
286
290
 
287
291
  p.render_elements(machine_outer.geom, Shape,
288
292
  draw_inside=True, title=outer_name,
289
293
  rows=3, cols=2, num=6, show=False,
290
- # with_nodes=True,
291
- # neighbors=True,
294
+ with_corners=False,
295
+ with_nodes=False,
296
+ neighbors=False,
292
297
  write_id=write_id,
293
298
  fill_areas=True)
294
299
  if write_png:
@@ -394,6 +399,7 @@ def convert(dxfile,
394
399
  machine = machine.undo_mirror()
395
400
  machine.geom.set_stator()
396
401
  machine.geom.search_stator_subregions(part[1])
402
+ machine.geom.looking_for_corners()
397
403
  machine.create_mirror_lines_outside_windings()
398
404
 
399
405
  params = create_femag_parameters_stator(machine,
@@ -401,20 +407,23 @@ def convert(dxfile,
401
407
  else:
402
408
  machine.geom.set_rotor()
403
409
  machine.geom.search_rotor_subregions(part[1])
410
+ machine.geom.looking_for_corners()
404
411
  params = create_femag_parameters_rotor(machine,
405
412
  part[1])
406
413
  else:
407
414
  machine.geom.search_subregions()
408
415
 
409
416
  machine.delete_tiny_elements(mindist)
417
+ machine.geom.create_corner_areas()
410
418
  logger.info("END of work: %s", basename)
411
419
 
412
420
  if show_plots:
413
421
  p.render_elements(machine.geom, Shape,
414
422
  draw_inside=True, title=name,
415
423
  rows=3, cols=2, num=5, show=False,
416
- # with_nodes=True,
417
- # neighbors=True,
424
+ with_corners=False,
425
+ with_nodes=False,
426
+ neighbors=False,
418
427
  write_id=write_id,
419
428
  fill_areas=True)
420
429
  if write_png:
@@ -110,14 +110,19 @@ class FslRenderer(object):
110
110
  # if self.nodedist > 0:
111
111
  # l = la.norm(np.asarray(p1)-p2)
112
112
  # num = int(l/self.nodedist + 1)
113
- if e is not None and e.has_attribute('auxline'):
114
- self.content.append(
115
- u"nc_line({}, {}, {}, {}, {}) -- auxiliary".format(
116
- p1[0], p1[1], p2[0], p2[1], num))
117
- else:
118
- self.content.append(
119
- u"nc_line({}, {}, {}, {}, {})".format(
120
- p1[0], p1[1], p2[0], p2[1], num))
113
+ if e is not None:
114
+ if e.has_attribute('no_fsl'):
115
+ logger.info("line with attr nofsl")
116
+ return
117
+ if e.has_attribute('auxline'):
118
+ self.content.append(
119
+ u"nc_line({}, {}, {}, {}, {}) -- auxiliary".format(
120
+ p1[0], p1[1], p2[0], p2[1], num))
121
+ return
122
+
123
+ self.content.append(
124
+ u"nc_line({}, {}, {}, {}, {})".format(
125
+ p1[0], p1[1], p2[0], p2[1], num))
121
126
 
122
127
  def sorted_elements(self, geom, inner=False):
123
128
  if inner:
@@ -288,7 +288,7 @@ def is_same_angle(angle1, angle2, atol=0.001):
288
288
  np.isclose(np.sin(angle1), np.sin(angle2), atol=atol))
289
289
 
290
290
 
291
- def part_of_circle(startangle, endangle, dec_place=3):
291
+ def part_of_circle(startangle, endangle, dec_place=2):
292
292
  """ returns the number of segments included in the circle
293
293
  if an integer number, 0 otherwise
294
294
  """