femagtools 1.3.1__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.
femagtools/__init__.py CHANGED
@@ -9,7 +9,7 @@
9
9
 
10
10
  """
11
11
  __title__ = 'femagtools'
12
- __version__ = '1.3.1'
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
@@ -314,7 +314,8 @@ class Amela():
314
314
  bndy=[float(c) for c in bndy[i]],
315
315
  bl=bl[i],
316
316
  elcp=elcp[i],
317
- area=spel_area[i]))
317
+ area=spel_area[i],
318
+ spel_key=spel_key[i]))
318
319
  pm_data[i].update(pos)
319
320
 
320
321
  for k in range(len(pm_node_key)):
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
@@ -1056,6 +1058,12 @@ class Area(object):
1056
1058
  return True
1057
1059
  return False
1058
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
+
1059
1067
  def mark_stator_subregions(self,
1060
1068
  is_inner,
1061
1069
  stator_size,
@@ -1155,18 +1163,37 @@ class Area(object):
1155
1163
  logger.debug("***** air (part of a circle)\n")
1156
1164
  return self.type
1157
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
+
1158
1177
  if self.min_angle > 0.001:
1159
1178
  if self.max_angle < alpha - 0.001:
1160
- self.type = 2 # windings
1161
- 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")
1162
1185
  return self.type
1163
1186
  if mirrored:
1164
- self.type = 2 # windings
1165
- 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")
1166
1193
  return self.type
1167
1194
 
1168
1195
  self.type = 0 # air
1169
- logger.debug("***** air #2")
1196
+ logger.debug("***** air #3")
1170
1197
 
1171
1198
  if self.close_to_startangle or self.close_to_endangle:
1172
1199
  f = self.surface / stator_size
@@ -1179,7 +1206,7 @@ class Area(object):
1179
1206
  logger.debug("***** air or iron close to border\n")
1180
1207
  return self.type
1181
1208
 
1182
- logger.debug("***** air #3\n")
1209
+ logger.debug("***** air #4\n")
1183
1210
  return 0
1184
1211
 
1185
1212
  def mark_rotor_subregions(self, is_inner, mirrored, alpha,
@@ -1331,6 +1358,15 @@ class Area(object):
1331
1358
  logger.debug(">>> air remains")
1332
1359
  return self.type
1333
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
+
1334
1370
  def area_size(self):
1335
1371
  nodes = [n for n in self.list_of_nodes()]
1336
1372
  return area_size(nodes)
@@ -1467,14 +1503,19 @@ class Area(object):
1467
1503
 
1468
1504
  def __str__(self):
1469
1505
  return "Area {}\n".format(self.id) + \
1470
- "distance: from {} to {}\n".\
1506
+ "distance...............: from {} to {}\n".\
1471
1507
  format(round(self.min_dist, 4), round(self.max_dist, 4)) + \
1472
- "height..: {}\n".format(self.height) + \
1473
- "alpha...: {}\n".format(self.alpha) + \
1474
- "angle...: from {} to {}\n".\
1508
+ "height.................: {}\n".format(self.height) + \
1509
+ "alpha..................: {}\n".format(self.alpha) + \
1510
+ "angle..................: from {} to {}\n".\
1475
1511
  format(round(self.min_angle, 6), round(self.max_angle, 6)) + \
1476
- "delta...: {}\n".format(self.delta) + \
1477
- "number..: {}\n".format(self.count) + \
1478
- "equal...: {}\n".format(len(self.equal_areas)) + \
1479
- "symmetry: {}\n".format(self.symmetry) + \
1480
- "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)
@@ -399,6 +399,7 @@ def convert(dxfile,
399
399
  machine = machine.undo_mirror()
400
400
  machine.geom.set_stator()
401
401
  machine.geom.search_stator_subregions(part[1])
402
+ machine.geom.looking_for_corners()
402
403
  machine.create_mirror_lines_outside_windings()
403
404
 
404
405
  params = create_femag_parameters_stator(machine,
@@ -406,6 +407,7 @@ def convert(dxfile,
406
407
  else:
407
408
  machine.geom.set_rotor()
408
409
  machine.geom.search_rotor_subregions(part[1])
410
+ machine.geom.looking_for_corners()
409
411
  params = create_femag_parameters_rotor(machine,
410
412
  part[1])
411
413
  else:
femagtools/dxfsl/geom.py CHANGED
@@ -276,6 +276,32 @@ def lw_polyline(entity, lf, xoff=0.0, yoff=0.0, rotation=0.0):
276
276
  xoff=xoff, yoff=yoff,
277
277
  rotation=rotation)
278
278
 
279
+ def ellipse(entity, lf, xoff=0.0, yoff=0.0, rotation=0.0):
280
+ w = np.linalg.norm(entity.major_axis) * 2
281
+ h = entity.ratio * w
282
+ theta = np.arctan2(entity.major_axis[1], entity.major_axis[0])
283
+ start_angle = entity.start_param
284
+ end_angle = entity.end_param
285
+ if end_angle < start_angle:
286
+ end_angle += 2*np.pi
287
+ alfa = np.linspace(start_angle, end_angle, 20)
288
+ x = 0.5 * w * np.cos(alfa)
289
+ y = 0.5 * h * np.sin(alfa)
290
+ R = np.array([
291
+ [np.cos(theta), -np.sin(theta)],
292
+ [np.sin(theta), np.cos(theta)]
293
+ ])
294
+ x, y = np.dot(R, [x, y])
295
+ x += entity.center[0]
296
+ y += entity.center[1]
297
+ points = np.array((x,y)).T
298
+ p1 = points[0]
299
+ for p2 in points[1:]:
300
+ yield Line(Element(start=p1, end=p2), lf,
301
+ xoff=xoff, yoff=yoff,
302
+ rotation=rotation)
303
+ p1 = p2
304
+
279
305
 
280
306
  def spline(entity, lf, min_dist=0.001, xoff=0.0, yoff=0.0, rotation=0.0):
281
307
  if False:
@@ -493,22 +519,26 @@ def dxfshapes(dxffile, mindist=0.01, layers=[]):
493
519
  for l in insert_block(dwg, e, lf, rf, block, min_dist=mindist):
494
520
  yield l
495
521
  elif e.dxftype == 'ELLIPSE':
496
- w = np.linalg.norm(e.major_axis) * 2
497
- h = e.ratio * w
498
- rtheta = np.arctan2(e.major_axis[1], e.major_axis[0])
499
- angle = rtheta*180/np.pi
500
- start_angle = e.start_param*180/np.pi + angle
501
- end_angle = e.end_param*180/np.pi + angle
502
- arc = Arc(Element(center=e.center,
503
- radius=w/2,
504
- start_angle=start_angle,
505
- end_angle=end_angle,
506
- width=w,
507
- height=h,
508
- rtheta=rtheta,
509
- start_param=e.start_param,
510
- end_param=e.end_param))
511
- yield arc
522
+ for l in ellipse(e, lf):
523
+ yield l
524
+ #w = np.linalg.norm(e.major_axis) * 2
525
+ #h = e.ratio * w
526
+ #rtheta = np.arctan2(e.major_axis[1], e.major_axis[0])
527
+ #angle = rtheta*180/np.pi
528
+ #start_angle = e.start_param*180/np.pi + angle
529
+ #end_angle = e.end_param*180/np.pi + angle
530
+ #if end_angle < start_angle:
531
+ # end_angle += 360
532
+ #arc = Arc(Element(center=e.center,
533
+ # radius=w/2,
534
+ # start_angle=start_angle,
535
+ # end_angle=end_angle,
536
+ # width=w,
537
+ # height=h,
538
+ # rtheta=rtheta,
539
+ # start_param=e.start_param,
540
+ # end_param=e.end_param))
541
+ #yield arc
512
542
 
513
543
  elif e.dxftype == 'POINT':
514
544
  logger.debug("Id %d4: type %s ignored", id, e.dxftype)
@@ -994,12 +1024,28 @@ class Geometry(object):
994
1024
  def add_line(self, n1, n2, color=None):
995
1025
  line = Line(Element(start=n1, end=n2), color=color)
996
1026
  add_or_join(self,
997
- line.node1(ndec),
998
- line.node2(ndec),
1027
+ n1,
1028
+ n2,
999
1029
  line,
1000
1030
  self.rtol,
1001
1031
  self.atol)
1002
1032
 
1033
+ def add_arc(self, n1, n2, center, radius, color=None):
1034
+ angle_n1 = alpha_line(center, n1)
1035
+ angle_n2 = alpha_line(center, n2)
1036
+ arc = Arc(Element(center=center,
1037
+ radius=radius,
1038
+ start_angle=angle_n1*180/np.pi,
1039
+ end_angle=angle_n2*180/np.pi),
1040
+ color=color)
1041
+ add_or_join(self,
1042
+ n1,
1043
+ n2,
1044
+ arc,
1045
+ self.rtol,
1046
+ self.atol)
1047
+
1048
+
1003
1049
  def elements(self, type):
1004
1050
  """return lists of objects"""
1005
1051
  return [e[2]['object'] for e in self.g.edges(data=True)
@@ -2631,7 +2677,7 @@ class Geometry(object):
2631
2677
  dist_max = max(dist_max, g[1])
2632
2678
  return airgaps
2633
2679
 
2634
- def detect_airgaps(self, center, startangle, endangle, atol):
2680
+ def detect_airgaps(self, center, startangle, endangle, atol=0.1, with_end=False):
2635
2681
  """ Die Funktion sucht Luftspalt-Kandidaten und liefert eine Liste
2636
2682
  von Möglichkeiten mit jeweils einem minimalen und einem maximalen
2637
2683
  Radius als Begrenzung des Luftspalts.
@@ -2651,6 +2697,8 @@ class Geometry(object):
2651
2697
  min_radius = self.min_radius + 1.0
2652
2698
  cur_radius = gaplist[0][1]
2653
2699
  max_radius = self.max_radius - 1.0
2700
+ if with_end:
2701
+ max_radius = self.max_radius + 1.0
2654
2702
 
2655
2703
  for g in gaplist:
2656
2704
  if greater(g[0], cur_radius) and \
@@ -3024,13 +3072,31 @@ class Geometry(object):
3024
3072
 
3025
3073
  def search_subregions(self):
3026
3074
  if self.is_stator():
3027
- return self.search_stator_subregions()
3075
+ self.search_stator_subregions()
3076
+ elif self.is_rotor():
3077
+ self.search_rotor_subregions()
3078
+ else:
3079
+ logger.warning("no stator or rotor assigned")
3080
+ self.search_unknown_subregions()
3081
+ self.looking_for_corners()
3028
3082
 
3029
- if self.is_rotor():
3030
- return self.search_rotor_subregions()
3083
+ def collect_windings(self):
3084
+ found = True
3085
+ while found:
3086
+ windings = [a for a in self.list_of_areas()
3087
+ if a.type == 2]
3088
+ bad_windings = [a for a in self.list_of_areas()
3089
+ if a.type == 12]
3090
+ if not bad_windings:
3091
+ return windings
3092
+
3093
+ found = False
3094
+ for a in bad_windings:
3095
+ if a.is_touching_areas(windings):
3096
+ a.type = 2
3097
+ found = True
3031
3098
 
3032
- logger.warning("no stator or rotor assigned")
3033
- return self.search_unknown_subregions()
3099
+ return [a for a in self.list_of_areas() if a.type == 2]
3034
3100
 
3035
3101
  def search_stator_subregions(self, place=''):
3036
3102
  logger.debug("Begin of search_stator_subregions")
@@ -3053,8 +3119,8 @@ class Geometry(object):
3053
3119
  self.min_radius,
3054
3120
  self.max_radius)
3055
3121
 
3056
- windings = [a for a in self.list_of_areas()
3057
- if a.type == 2]
3122
+ windings = self.collect_windings()
3123
+ [a.set_type(0) for a in self.list_of_areas() if a.type == 12]
3058
3124
  windings_found = len(windings)
3059
3125
  logger.info("%d windings found", windings_found)
3060
3126
 
@@ -3063,7 +3129,7 @@ class Geometry(object):
3063
3129
  windings_surface.sort(reverse=True)
3064
3130
  max_size = windings_surface[0][0]
3065
3131
  for sz, w in windings_surface:
3066
- logger.info("winding size = %s", sz)
3132
+ logger.debug("winding size = %s", sz)
3067
3133
  if sz / max_size < 0.95:
3068
3134
  w.set_type(0)
3069
3135
  if sz / max_size < 0.2:
@@ -3328,7 +3394,21 @@ class Geometry(object):
3328
3394
  if a.surface < max_surface * 0.20: # too small
3329
3395
  a.set_type(0) # air
3330
3396
 
3331
- logger.debug("begin of search_unknown_subregions")
3397
+ logger.debug("end of search_unknown_subregions")
3398
+
3399
+ def looking_for_corners(self):
3400
+ if self.is_inner:
3401
+ logger.debug("looking_for_corners: inner")
3402
+ start_cp = self.start_corners[-1]
3403
+ end_cp = self.end_corners[-1]
3404
+ else:
3405
+ logger.debug("looking_for_corners: outer")
3406
+ start_cp = self.start_corners[0]
3407
+ end_cp = self.end_corners[0]
3408
+ logger.debug("looking_for_corners: start=%s, end=%s",
3409
+ start_cp, end_cp)
3410
+ for area in self.list_of_areas():
3411
+ area.mark_airgap_corners(start_cp, end_cp)
3332
3412
  return
3333
3413
 
3334
3414
  def num_areas_of_type(self, type):
@@ -3581,19 +3661,16 @@ class Geometry(object):
3581
3661
  c += self.remove_appendix(n2, nbrs[0], incr_text + '.')
3582
3662
  return c
3583
3663
 
3584
- def split_and_get_intersect_points(self, center, outer_radius, angle):
3664
+ def split_and_get_intersect_points(self, el, aktion=True):
3585
3665
  logger.debug("begin of split_and_get_intersect_points")
3586
3666
  rtol = 1e-03
3587
3667
  atol = 1e-03
3588
- line = Line(
3589
- Element(start=center,
3590
- end=point(center, outer_radius+1, angle)))
3591
3668
  points = []
3592
3669
  for e in self.elements(Shape):
3593
- pts = e.intersect_line(line,
3594
- rtol=rtol,
3595
- atol=atol,
3596
- include_end=True)
3670
+ pts = e.intersect_shape(el,
3671
+ rtol=rtol,
3672
+ atol=atol,
3673
+ include_end=True)
3597
3674
  if pts:
3598
3675
  pts_inside = []
3599
3676
  pts_real = []
@@ -3608,7 +3685,7 @@ class Geometry(object):
3608
3685
  pts_real.append(p)
3609
3686
  pts_inside.append(p)
3610
3687
 
3611
- if pts_inside:
3688
+ if pts_inside and aktion:
3612
3689
  self.remove_edge(e)
3613
3690
  elements = e.split(pts_inside, rtol, atol)
3614
3691
  for e in elements:
@@ -3631,6 +3708,31 @@ class Geometry(object):
3631
3708
  return True
3632
3709
  return False
3633
3710
 
3711
+ def inside_area_list(self, p):
3712
+ for area in self.list_of_areas():
3713
+ if area.is_point_inside(p):
3714
+ yield area
3715
+
3716
+ def critical_touch_point(self, points):
3717
+ logger.debug("looking for critical touch-point")
3718
+ winding_touched = False
3719
+ for p in points[1:]:
3720
+ d = distance(self.center, p)
3721
+ logger.debug("-- p = %s, dist = %s", p, d)
3722
+ for a in self.inside_area_list(p):
3723
+ logger.debug("-- Area type = %s", a.type)
3724
+ logger.debug(" min=%s, max= %s", a.min_dist, a.max_dist)
3725
+ logger.debug(" close to start = %s", a.close_to_startangle)
3726
+ logger.debug(" close to end = %s", a.close_to_endangle)
3727
+ if a.is_winding():
3728
+ winding_touched = True
3729
+ else:
3730
+ if winding_touched and greater(a.max_dist, d, atol=0.001):
3731
+ if not (a.close_to_startangle and a.close_to_endangle):
3732
+ logger.debug("-- return %s", p)
3733
+ return p
3734
+ return None
3735
+
3634
3736
  def create_lines_outside_windings(self, points):
3635
3737
  if not points:
3636
3738
  return False
@@ -3661,16 +3763,23 @@ class Geometry(object):
3661
3763
  return False
3662
3764
 
3663
3765
  def get_inner_airgap_line(self):
3766
+ logger.debug("begin of get_inner_airgap_line")
3767
+
3664
3768
  if not self.is_inner:
3769
+ logger.debug("end of get_inner_airgap_line: not inner")
3665
3770
  return []
3666
- area = [a for a in self.area_list if a.close_to_endangle and a.close_to_ag]
3771
+ for a in self.area_list:
3772
+ logger.debug("%s", a)
3773
+ area = [a for a in self.area_list if a.close_to_ag_endcorner]
3667
3774
  if len(area) != 1:
3775
+ logger.debug("end of get_inner_airgap_line: %s areas found", len(area))
3668
3776
  return []
3669
3777
 
3670
3778
  end_corner = self.end_corners[-1]
3671
3779
  logger.debug("END CORNER %s", end_corner)
3672
3780
  nodes = [n for n in area[0].list_of_nodes()]
3673
3781
  if not nodes:
3782
+ logger.debug("end of get_inner_airgap_line: no nodes found")
3674
3783
  return []
3675
3784
  n1 = nodes[0]
3676
3785
  if points_are_close(end_corner, n1):
@@ -3683,6 +3792,7 @@ class Geometry(object):
3683
3792
  n2 = n1
3684
3793
 
3685
3794
  if not points_are_close(end_corner, n1):
3795
+ logger.debug("end of get_inner_airgap_line: not close to endcorner")
3686
3796
  return []
3687
3797
 
3688
3798
  start_corner = self.start_corners[-1]
@@ -3697,6 +3807,7 @@ class Geometry(object):
3697
3807
  n2 = info['n2']
3698
3808
  nodes.append(n2)
3699
3809
 
3810
+ logger.debug("end of get_inner_airgap_line #%s", len(nodes))
3700
3811
  return nodes
3701
3812
 
3702
3813
  def create_corner_areas(self):
@@ -3743,7 +3854,11 @@ class Geometry(object):
3743
3854
  if not self.search_intersection(i, self.max_radius,
3744
3855
  n, start_cp,
3745
3856
  airgap_nodes):
3746
- self.add_line(start_cp, n, color='red')
3857
+ d = distance(self.center, n)
3858
+ if np.isclose(d, self.max_radius):
3859
+ self.add_arc(start_cp, n, self.center, self.max_radius, color='red')
3860
+ else:
3861
+ self.add_line(start_cp, n, color='red')
3747
3862
  self.add_edge(cp, start_cp, start_line)
3748
3863
  self.create_and_append_area(start_cp, n)
3749
3864
  self.start_corners = self.get_corner_nodes(self.center,
@@ -3762,7 +3877,11 @@ class Geometry(object):
3762
3877
  if not self.search_intersection(i, self.max_radius,
3763
3878
  n, end_cp,
3764
3879
  airgap_nodes):
3765
- self.add_line(end_cp, n, color='red')
3880
+ d = distance(self.center, n)
3881
+ if np.isclose(d, self.max_radius):
3882
+ self.add_arc(n, end_cp, self.center, self.max_radius, color='red')
3883
+ else:
3884
+ self.add_line(end_cp, n, color='red')
3766
3885
  self.add_edge(cp, end_cp, end_line)
3767
3886
  self.create_and_append_area(n, end_cp)
3768
3887
  self.end_corners = self.get_corner_nodes(self.center,
@@ -3788,7 +3907,7 @@ class Geometry(object):
3788
3907
  logger.debug("end of search_intersection: bad")
3789
3908
  return True # fatal
3790
3909
  dist_p = distance(self.center, pts[0])
3791
- logger.info("-- check point %s[%s] -- %s[%s]", n, dist_n, pts[0], dist_p)
3910
+ logger.debug("-- check point %s[%s] -- %s[%s]", n, dist_n, pts[0], dist_p)
3792
3911
  if not less(dist_n, dist_p):
3793
3912
  logger.debug("end of search_intersection: found")
3794
3913
  return True # intersection