femagtools 1.8.1__py3-none-any.whl → 1.8.3__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 (49) hide show
  1. femagtools/__init__.py +1 -1
  2. femagtools/dxfsl/area.py +110 -1
  3. femagtools/dxfsl/areabuilder.py +93 -45
  4. femagtools/dxfsl/conv.py +5 -0
  5. femagtools/dxfsl/converter.py +85 -27
  6. femagtools/dxfsl/fslrenderer.py +5 -4
  7. femagtools/dxfsl/functions.py +14 -6
  8. femagtools/dxfsl/geom.py +135 -149
  9. femagtools/dxfsl/journal.py +1 -1
  10. femagtools/dxfsl/machine.py +161 -9
  11. femagtools/dxfsl/shape.py +46 -1
  12. femagtools/dxfsl/svgparser.py +1 -1
  13. femagtools/dxfsl/symmetry.py +143 -38
  14. femagtools/femag.py +64 -61
  15. femagtools/fsl.py +15 -12
  16. femagtools/isa7.py +3 -2
  17. femagtools/machine/__init__.py +5 -4
  18. femagtools/machine/afpm.py +79 -33
  19. femagtools/machine/effloss.py +29 -18
  20. femagtools/machine/sizing.py +192 -13
  21. femagtools/machine/sm.py +34 -36
  22. femagtools/machine/utils.py +2 -2
  23. femagtools/mcv.py +58 -29
  24. femagtools/model.py +4 -3
  25. femagtools/multiproc.py +79 -80
  26. femagtools/parstudy.py +11 -5
  27. femagtools/plot/nc.py +2 -2
  28. femagtools/semi_fea.py +108 -0
  29. femagtools/templates/basic_modpar.mako +0 -3
  30. femagtools/templates/fe-contr.mako +18 -18
  31. femagtools/templates/ld_lq_fast.mako +3 -0
  32. femagtools/templates/mult_cal_fast.mako +3 -0
  33. femagtools/templates/pm_sym_f_cur.mako +4 -1
  34. femagtools/templates/pm_sym_fast.mako +3 -0
  35. femagtools/templates/pm_sym_loss.mako +3 -0
  36. femagtools/templates/psd_psq_fast.mako +3 -0
  37. femagtools/templates/torq_calc.mako +3 -0
  38. femagtools/tks.py +23 -20
  39. femagtools/zmq.py +213 -0
  40. {femagtools-1.8.1.dist-info → femagtools-1.8.3.dist-info}/METADATA +3 -3
  41. {femagtools-1.8.1.dist-info → femagtools-1.8.3.dist-info}/RECORD +49 -47
  42. {femagtools-1.8.1.dist-info → femagtools-1.8.3.dist-info}/WHEEL +1 -1
  43. tests/test_afpm.py +15 -6
  44. tests/test_femag.py +1 -1
  45. tests/test_fsl.py +4 -4
  46. tests/test_mcv.py +21 -15
  47. {femagtools-1.8.1.dist-info → femagtools-1.8.3.dist-info}/LICENSE +0 -0
  48. {femagtools-1.8.1.dist-info → femagtools-1.8.3.dist-info}/entry_points.txt +0 -0
  49. {femagtools-1.8.1.dist-info → femagtools-1.8.3.dist-info}/top_level.txt +0 -0
@@ -85,16 +85,24 @@ def alpha_angle(startangle, endangle):
85
85
  return angle - 2.0*np.pi
86
86
 
87
87
 
88
- def max_angle(alpha1, alpha2):
88
+ def less_angle(alpha1, alpha2):
89
89
  angle = alpha_angle(alpha1, alpha2)
90
- if angle < np.pi or angle > 2.0*np.pi:
91
- return alpha2
92
- return alpha1
90
+ return (angle < np.pi or angle > 2.0*np.pi)
93
91
 
94
92
 
95
- def min_angle(alpha1, alpha2):
93
+ def greater_angle(alpha1, alpha2):
96
94
  angle = alpha_angle(alpha1, alpha2)
97
- if angle < np.pi or angle > 2.0*np.pi:
95
+ return not (angle < np.pi or angle > 2.0*np.pi)
96
+
97
+
98
+ def max_angle(alpha1, alpha2):
99
+ if greater_angle(alpha1, alpha2):
100
+ return alpha1
101
+ return alpha2
102
+
103
+
104
+ def min_angle(alpha1, alpha2):
105
+ if less_angle(alpha1, alpha2):
98
106
  return alpha1
99
107
  return alpha2
100
108
 
femagtools/dxfsl/geom.py CHANGED
@@ -235,6 +235,9 @@ def single_path(edges):
235
235
 
236
236
  nodes_filecount = 0
237
237
 
238
+ TYPE_UNDEFINED = 0
239
+ TYPE_ROTOR = 1
240
+ TYPE_STATOR = 2
238
241
 
239
242
  class Geometry(object):
240
243
  """collection of connected shapes"""
@@ -252,6 +255,7 @@ class Geometry(object):
252
255
  delete=False,
253
256
  adjust=False,
254
257
  main=False,
258
+ type=TYPE_UNDEFINED,
255
259
  debug=False):
256
260
  self._name = ''
257
261
  self.kind = ''
@@ -260,6 +264,7 @@ class Geometry(object):
260
264
  self.end_corners = []
261
265
  self.sym_part = 0
262
266
  self.sym_counterpart = 0
267
+ self.sym_type = type
263
268
  self.sym_slices = 0
264
269
  self.sym_slice_angle = 0.0
265
270
  self.alfa = 0.0
@@ -440,10 +445,12 @@ class Geometry(object):
440
445
  is_inner=self.is_inner,
441
446
  is_outer=self.is_outer,
442
447
  rtol=self.rtol,
443
- atol=self.atol)
448
+ atol=self.atol,
449
+ type=self.sym_type)
444
450
  geom.alfa = correct_alpha
445
451
  geom.kind = self.kind
446
452
  geom.sym_part = self.sym_part
453
+ geom.sym_type = self.sym_type
447
454
  return geom
448
455
 
449
456
  def log_geom(self):
@@ -861,6 +868,12 @@ class Geometry(object):
861
868
  def start_max_corner(self, i):
862
869
  return self.start_corners[-1][i]
863
870
 
871
+ def get_start_airgap_node(self):
872
+ if self.is_inner:
873
+ return self.start_corners[-1]
874
+ else:
875
+ return self.start_corners[0]
876
+
864
877
  def dist_start_max_corner(self):
865
878
  logger.debug("begin of dist_start_max_corner")
866
879
  logger.debug("start corners: %s", self.start_corners)
@@ -868,16 +881,21 @@ class Geometry(object):
868
881
  logger.debug("end of dist_start_max_corner: %s", d)
869
882
  return d
870
883
 
871
- def dist_end_max_corner(self):
884
+ def dist_end_max_corner(self, mirrored=True):
872
885
  logger.debug("begin of dist_end_max_corner")
873
886
  logger.debug("end corners: %s", self.end_corners)
874
887
 
875
- if self.is_mirrored():
888
+ if self.is_mirrored() and mirrored:
876
889
  return self.dist_start_max_corner()
877
890
  d = distance(self.center, self.end_corners[-1])
878
891
  logger.debug("end of dist_end_max_corner: %s", d)
879
892
  return d
880
893
 
894
+ def max_corners_match(self):
895
+ d1 = self.dist_start_max_corner()
896
+ d2 = self.dist_end_max_corner(mirrored=False)
897
+ return np.isclose(d1, d2, rtol=1e-3, atol=1e-3)
898
+
881
899
  def dist_start_min_corner(self):
882
900
  logger.debug("begin of dist_start_min_corner")
883
901
  logger.debug("start corners: %s", self.start_corners)
@@ -885,16 +903,24 @@ class Geometry(object):
885
903
  logger.debug("end of dist_start_min_corner: %s", d)
886
904
  return d
887
905
 
888
- def dist_end_min_corner(self):
906
+ def dist_end_min_corner(self, mirrored=True):
889
907
  logger.debug("begin of dist_end_min_corner")
890
908
  logger.debug("end corners: %s", self.end_corners)
891
909
 
892
- if self.is_mirrored():
910
+ if self.is_mirrored() and mirrored:
893
911
  return self.dist_start_min_corner()
894
912
  d = distance(self.center, self.end_corners[0])
895
913
  logger.debug("end of dist_end_min_corner: %s", d)
896
914
  return d
897
915
 
916
+ def min_corners_match(self):
917
+ d1 = self.dist_start_min_corner()
918
+ d2 = self.dist_end_min_corner(mirrored=False)
919
+ return np.isclose(d1, d2, rtol=1e-3, atol=1e-3)
920
+
921
+ def min_max_corners_match(self):
922
+ return self.min_corners_match() and self.max_corners_match()
923
+
898
924
  def get_start_airgap_corner(self):
899
925
  if self.is_inner:
900
926
  p = (self.max_radius, 0.0)
@@ -1146,9 +1172,12 @@ class Geometry(object):
1146
1172
  nx.set_edge_attributes(self.g, False, 1)
1147
1173
  nx.set_edge_attributes(self.g, False, 2)
1148
1174
 
1149
- def create_list_of_areas(self, main=False):
1175
+ def create_list_of_areas(self, main=False, delete=False):
1150
1176
  """ return list of areas for each node and their neighbors
1151
1177
  """
1178
+ if delete: # clear list of areas
1179
+ self.area_list = []
1180
+
1152
1181
  if len(self.area_list) > 0:
1153
1182
  logger.debug("area list already available")
1154
1183
  # list already available
@@ -1553,7 +1582,8 @@ class Geometry(object):
1553
1582
  concatenate=concatenate,
1554
1583
  connect=connect,
1555
1584
  delete=delete_appendices,
1556
- split=split)
1585
+ split=split,
1586
+ type=self.sym_type)
1557
1587
  geom.with_center_node = self.with_center_node
1558
1588
 
1559
1589
  logger.debug('end copy_shape')
@@ -1614,7 +1644,8 @@ class Geometry(object):
1614
1644
  split=split,
1615
1645
  concatenate=concatenate,
1616
1646
  connect=connect,
1617
- adjust=adjust)
1647
+ adjust=adjust,
1648
+ type=self.sym_type)
1618
1649
 
1619
1650
  def is_new_angle(self, alpha_list, alpha):
1620
1651
  for a in alpha_list:
@@ -1704,6 +1735,13 @@ class Geometry(object):
1704
1735
  def symmetry_endangle(self):
1705
1736
  return self.sym_area.sym_endangle
1706
1737
 
1738
+ def rotate_symmetry_parameters(self):
1739
+ self.sym_startangle += self.sym_slice_angle
1740
+ self.sym_endangle += self.sym_slice_angle
1741
+ if self.sym_area:
1742
+ self.sym_area.sym_startangle = self.sym_startangle
1743
+ self.sym_area.sym_endangle = self.sym_endangle
1744
+
1707
1745
  def get_symmetry_copies(self):
1708
1746
  if self.sym_counterpart == 0:
1709
1747
  return int(self.sym_part)
@@ -1948,7 +1986,7 @@ class Geometry(object):
1948
1986
  startangle=0.0,
1949
1987
  endangle=np.pi/2)
1950
1988
 
1951
- elif np.isclose(width, height*2, self.rtol, self.atol):
1989
+ elif np.isclose(width, height*2, rtol=1e-2, atol=1e-2):
1952
1990
  radius = width/2
1953
1991
  self.set_center([mm[1]-height, mm[2]])
1954
1992
  logger.info("check for half machine")
@@ -1967,7 +2005,7 @@ class Geometry(object):
1967
2005
  startangle=np.pi,
1968
2006
  endangle=0.0)
1969
2007
 
1970
- elif np.isclose(width*2, height, self.rtol, self.atol):
2008
+ elif np.isclose(width*2, height, rtol=1e-2, atol=1e-2):
1971
2009
  radius = width
1972
2010
  logger.info("check for half machine")
1973
2011
  self.set_center([mm[1], mm[3]-width])
@@ -2371,31 +2409,31 @@ class Geometry(object):
2371
2409
  logger.debug("end check_airgap: return %s", len(area_id_list) > 1)
2372
2410
  return len(area_id_list) > 1 # bad
2373
2411
 
2374
- def is_border_line(self, center, startangle, endangle, e, atol):
2412
+ def is_border_line(self, center, startangle, endangle, e, rtol=1e-3, atol=1e-3):
2375
2413
  if isinstance(e, Line):
2376
2414
  if np.isclose(startangle, endangle):
2377
2415
  return False # full
2378
2416
 
2379
2417
  if points_are_close(center, e.p1):
2380
2418
  angle_p2 = alpha_line(center, e.p2)
2381
- if np.isclose(startangle, angle_p2, 1e-3, atol):
2419
+ if np.isclose(startangle, angle_p2, rtol=rtol, atol=atol):
2382
2420
  return True
2383
- return np.isclose(endangle, angle_p2, 1e-3, atol)
2421
+ return np.isclose(endangle, angle_p2, rtol=rtol, atol=atol)
2384
2422
 
2385
2423
  if points_are_close(center, e.p2):
2386
2424
  angle_p1 = alpha_line(center, e.p1)
2387
- if np.isclose(startangle, angle_p1, 1e-3, atol):
2425
+ if np.isclose(startangle, angle_p1, rtol=rtol, atol=atol):
2388
2426
  return True
2389
- return np.isclose(endangle, angle_p1, 1e-3, atol)
2427
+ return np.isclose(endangle, angle_p1, rtol=rtol, atol=atol)
2390
2428
 
2391
2429
  angle_p1 = alpha_line(center, e.p1)
2392
- if np.isclose(startangle, angle_p1, 1e-3, atol):
2430
+ if np.isclose(startangle, angle_p1, rtol=rtol, atol=atol):
2393
2431
  angle_p2 = alpha_line(center, e.p2)
2394
- return np.isclose(startangle, angle_p2, 1e-3, atol)
2432
+ return np.isclose(startangle, angle_p2, rtol=rtol, atol=atol)
2395
2433
 
2396
- if np.isclose(endangle, angle_p1, 1e-3, atol):
2434
+ if np.isclose(endangle, angle_p1, rtol=rtol, atol=atol):
2397
2435
  angle_p2 = alpha_line(center, e.p2)
2398
- return np.isclose(endangle, angle_p2, 1e-3, atol)
2436
+ return np.isclose(endangle, angle_p2, rtol=rtol, atol=atol)
2399
2437
  return False
2400
2438
 
2401
2439
  def get_gaplist(self, center):
@@ -2419,7 +2457,7 @@ class Geometry(object):
2419
2457
  """
2420
2458
  gaplist = []
2421
2459
  for e in self.elements(Shape):
2422
- if not self.is_border_line(center, startangle, endangle, e, atol):
2460
+ if not self.is_border_line(center, startangle, endangle, e, atol=atol):
2423
2461
  gaplist += [e.minmax_from_center(center)]
2424
2462
  else:
2425
2463
  min_r, max_r = e.minmax_from_center(center)
@@ -2958,12 +2996,22 @@ class Geometry(object):
2958
2996
  self.sym_counterpart = 1
2959
2997
  self.sym_part = 2
2960
2998
 
2999
+ def force_to_be_rotor(self):
3000
+ self.sym_type = TYPE_ROTOR
3001
+
3002
+ def force_to_be_stator(self):
3003
+ self.sym_type = TYPE_STATOR
3004
+
2961
3005
  def is_rotor(self):
3006
+ if self.sym_type != TYPE_UNDEFINED:
3007
+ return self.sym_type == TYPE_ROTOR
2962
3008
  if self.sym_counterpart:
2963
3009
  return self.sym_part < self.sym_counterpart
2964
3010
  return False
2965
3011
 
2966
3012
  def is_stator(self):
3013
+ if self.sym_type != TYPE_UNDEFINED:
3014
+ return self.sym_type == TYPE_STATOR
2967
3015
  if self.sym_counterpart:
2968
3016
  return self.sym_part > self.sym_counterpart
2969
3017
  return False
@@ -3096,6 +3144,16 @@ class Geometry(object):
3096
3144
  for e in elist:
3097
3145
  e.init_attributes('lightblue', 'no_fsl')
3098
3146
 
3147
+ def set_subregion_parameters(self,
3148
+ startangle,
3149
+ endangle):
3150
+ for a in self.list_of_areas():
3151
+ a.set_subregion_parameters(self.is_inner,
3152
+ self.min_radius,
3153
+ self.max_radius,
3154
+ startangle,
3155
+ endangle)
3156
+
3099
3157
  def search_subregions(self, startangle, endangle, EESM, single=False):
3100
3158
  if self.is_stator():
3101
3159
  self.search_stator_subregions(startangle,
@@ -3555,22 +3613,33 @@ class Geometry(object):
3555
3613
  return
3556
3614
  elements = []
3557
3615
  for a in areas:
3558
- elements += a.elements()
3559
- geom = Geometry(elements, center=self.center)
3616
+ elements += a.copy_of_elements()
3617
+ geom = Geometry(elements, center=self.center, type=self.sym_type)
3618
+ geom.create_list_of_areas()
3619
+ mag_areas = geom.list_of_areas()
3620
+
3560
3621
  builder = AreaBuilder(geom=geom)
3561
- if builder.create_area_groups(areas):
3622
+ if builder.create_area_groups(mag_areas):
3562
3623
  return # bad
3563
3624
  group_list = builder.area_list
3564
- # for debugging
3565
- # self.areagroup_list = group_list
3625
+
3566
3626
  for group in group_list:
3567
3627
  if not group.is_magnet_rectangle():
3568
3628
  logger.debug("Warning: group is not a rectangle")
3569
3629
  group.set_type(AREA.TYPE_MAGNET_RECT)
3570
3630
  phi = group.get_magnet_orientation()
3571
3631
  for a in group.areas_of_group:
3572
- logger.debug("Replace phi %s by %s", a.phi, phi)
3573
3632
  a.phi = phi
3633
+ p = a.get_best_point_inside(geom)
3634
+ phi_set = False
3635
+ for area in areas:
3636
+ if area.the_point_is_inside_area(p):
3637
+ logger.debug("Replace phi %s by %s", area.phi, phi)
3638
+ area.phi = phi
3639
+ phi_set = True
3640
+ break
3641
+ if not phi_set:
3642
+ logger.warning("___MAGNET PHI NOT SET. AREA NOT FOUND IN GEOMETRY___")
3574
3643
 
3575
3644
  def search_unknown_subregions(self):
3576
3645
  logger.debug("begin of search_unknown_subregions")
@@ -3614,7 +3683,7 @@ class Geometry(object):
3614
3683
  def windings_in_the_middle(self, midangle):
3615
3684
  wdg_areas = [a for a in self.list_of_areas()
3616
3685
  if a.is_winding()]
3617
- logger.info("%s windings in geom", len(wdg_areas))
3686
+ logger.debug("%s windings in geom", len(wdg_areas))
3618
3687
  for a in wdg_areas:
3619
3688
  if greater(a.max_angle, midangle) and \
3620
3689
  less(a.min_angle, midangle):
@@ -3652,6 +3721,10 @@ class Geometry(object):
3652
3721
  AREA.TYPE_YOKE,
3653
3722
  AREA.TYPE_TOOTH,))
3654
3723
 
3724
+ def num_of_magnets(self):
3725
+ return self.num_areas_of_type((AREA.TYPE_MAGNET_AIRGAP,
3726
+ AREA.TYPE_MAGNET_RECT,))
3727
+
3655
3728
  def area_close_to_endangle(self, type):
3656
3729
  return len([area for area in self.list_of_areas()
3657
3730
  if area.is_type(type) and area.close_to_endangle])
@@ -4147,61 +4220,18 @@ class Geometry(object):
4147
4220
  return True
4148
4221
  return False
4149
4222
 
4150
- def get_inner_airgap_line(self):
4151
- logger.debug("begin of get_inner_airgap_line")
4152
-
4153
- if not self.is_inner:
4154
- logger.debug("end of get_inner_airgap_line: not inner")
4155
- return [], []
4156
- for a in self.area_list:
4157
- logger.debug("%s", a)
4158
- area = [a for a in self.area_list if a.close_to_ag_endcorner]
4159
- if len(area) != 1:
4160
- logger.debug("end of get_inner_airgap_line: %s areas found", len(area))
4161
- return [], []
4162
-
4163
- end_corner = self.end_corners[-1]
4164
- logger.debug("END CORNER %s", end_corner)
4165
- nodes = [n for n in area[0].list_of_nodes()]
4166
- if not nodes:
4167
- logger.debug("end of get_inner_airgap_line: no nodes found")
4168
- return [], []
4169
- n1 = nodes[0]
4170
- if points_are_close(end_corner, n1):
4171
- n2 = nodes[-1]
4172
- else:
4173
- n2 = n1
4174
- for n1 in nodes[1:]:
4175
- if points_are_close(end_corner, n1):
4176
- break
4177
- n2 = n1
4178
-
4179
- if not points_are_close(end_corner, n1):
4180
- logger.debug("end of get_inner_airgap_line: not close to endcorner")
4181
- return [], []
4182
-
4183
- start_corner = self.start_corners[-1]
4184
-
4185
- logger.debug("EDGE FOUND: %s - %s", n1, n2)
4186
- nodes = [n1, n2]
4187
- info = self.get_edge_info(n1, n2)
4188
- elements = [info.get('element', None)]
4189
- while not points_are_close(start_corner, n2):
4190
- info = self.next_edge_lefthand_side(info)
4191
- if not info:
4192
- return []
4193
- n2 = info['n2']
4194
- nodes.append(n2)
4195
- elements.append(info.get('element', None))
4196
-
4197
- logger.debug("end of get_inner_airgap_line #%s", len(nodes))
4198
- return nodes, elements
4199
-
4200
4223
  def create_inner_corner_areas(self, startangle, endangle):
4201
- self.set_edge_attributes()
4224
+ builder = AreaBuilder(geom=self)
4225
+ return builder.create_inner_corner_auxiliary_areas(startangle, endangle)
4226
+
4227
+ def close_outer_winding_areas(self):
4228
+ logger.debug("begin close_outer_winding_areas(%s areas)",
4229
+ len(self.area_list))
4202
4230
 
4203
4231
  builder = AreaBuilder(geom=self)
4204
- builder.create_inner_corner_auxiliary_areas(startangle, endangle)
4232
+ rslt = builder.close_outer_winding_areas()
4233
+ logger.debug("end close_outer_winding_areas (%s)", rslt)
4234
+ return rslt
4205
4235
 
4206
4236
  def repair_border_line(self, nodes):
4207
4237
  logger.debug("begin repair_border_line")
@@ -4403,78 +4433,34 @@ class Geometry(object):
4403
4433
  points += pts
4404
4434
  return points
4405
4435
 
4406
- def create_inner_corner_auxiliary_areas(self):
4407
- start_cp, start_exists = self.get_start_airgap_corner()
4408
- end_cp, end_exists = self.get_end_airgap_corner()
4409
- if start_exists and end_exists:
4410
- return
4411
- logger.debug("*** Corner Auxiliary Areas ***")
4412
- airgap_line, airgap_el = self.get_inner_airgap_line()
4413
- if not airgap_el:
4414
- logger.debug("no airgapline found")
4415
- return
4436
+ def mirror_all_areas(self, mirrorangle):
4437
+ axis_p = point(self.center, self.max_radius, mirrorangle)
4438
+ axis_m = line_m(self.center, axis_p)
4439
+ axis_n = line_n(self.center, axis_m)
4416
4440
 
4417
- logger.debug("airgapline found !!")
4418
- airgap_nodes = [n for n in airgap_line[1:]]
4419
- del airgap_nodes[-1]
4441
+ def add_element(e):
4442
+ n = self.find_nodes(e.start(), e.end())
4443
+ if not self.has_edge(n[0], n[1]):
4444
+ self.add_edge(n[0], n[1], e)
4420
4445
 
4421
- if not start_exists:
4422
- cp = self.start_corners[-1]
4423
- logger.debug("Start Corner: %s -- %s", cp, start_cp)
4424
- start_line = Line(Element(start=cp, end=start_cp),
4425
- color='red',
4426
- linestyle='dotted')
4427
-
4428
- start_cp = start_line.node2(ndec)
4429
- for n in airgap_nodes:
4430
- ag_line = Line(Element(start=start_cp, end=n))
4431
- points = self.get_intersection_points(airgap_el, ag_line, n)
4432
- if not points: # no intersection
4433
- d = distance(self.center, n)
4434
- if np.isclose(d, self.max_radius):
4435
- self.add_arc(start_cp, n, self.center, self.max_radius,
4436
- color='red',
4437
- linestyle='dotted')
4438
- else:
4439
- self.add_line(start_cp, n,
4440
- color='red',
4441
- linestyle='dotted')
4442
- self.add_element(start_line,
4443
- rtol=self.rtol,
4444
- atol=self.atol)
4445
- self.create_and_append_area(start_cp, n)
4446
- self.start_corners = self.get_corner_nodes(self.center,
4447
- 0.0)
4448
- break
4449
-
4450
- if not end_exists:
4451
- cp = self.end_corners[-1]
4452
- logger.debug("End Corner: %s -- %s", cp, end_cp)
4453
- end_line = Line(Element(start=cp, end=end_cp),
4454
- color='red',
4455
- linestyle='dotted')
4456
- end_cp = end_line.node2(ndec)
4457
- airgap_nodes.reverse()
4458
- for n in airgap_nodes:
4459
- ag_line = Line(Element(start=end_cp, end=n))
4460
- points = self.get_intersection_points(airgap_el, ag_line, n)
4461
- if not points: # no intersection
4462
- d = distance(self.center, n)
4463
- if np.isclose(d, self.max_radius):
4464
- self.add_arc(n, end_cp, self.center, self.max_radius,
4465
- color='red',
4466
- linestyle='dotted')
4467
- else:
4468
- self.add_line(end_cp, n,
4469
- color='red',
4470
- linestyle='dotted')
4471
- self.add_element(end_line,
4472
- rtol=self.rtol,
4473
- atol=self.atol)
4474
- self.create_and_append_area(n, end_cp)
4475
- self.end_corners = self.get_corner_nodes(self.center,
4476
- self.alfa)
4477
- break
4446
+ area_list = []
4447
+ for a in self.area_list:
4448
+ area = a.mirror_area(self.center, axis_m, axis_n)
4449
+ area_list.append(area)
4450
+ for e in area.elements():
4451
+ add_element(e)
4452
+ self.area_list += area_list
4453
+
4454
+ def check_airgap_connecting_nodes(self, geom, startangle, endangle):
4455
+ logger.info("check_airgap_connecting_nodes")
4456
+
4457
+ start_node_in = self.get_start_airgap_node()
4458
+ start_node_out = geom.get_start_airgap_node()
4459
+ angle_in = alpha_line(self.center, start_node_in)
4460
+ angle_out = alpha_line(self.center, start_node_out)
4461
+ if np.isclose(angle_in, angle_out):
4462
+ return
4463
+ logger.warning("WARNING: airgap connecting nodes do not aline")
4478
4464
 
4479
4465
  def print_nodes(self):
4480
4466
  print("=== List of Nodes ({}) ===".format(self.number_of_nodes()))
@@ -18,7 +18,7 @@ logger = logging.getLogger('femagtools.journal')
18
18
  journal = None
19
19
 
20
20
  #############################
21
- # concat #
21
+ # journal #
22
22
  #############################
23
23
 
24
24