femagtools 1.8.0__py3-none-any.whl → 1.8.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 +1 -1
- femagtools/dxfsl/area.py +47 -3
- femagtools/dxfsl/areabuilder.py +93 -45
- femagtools/dxfsl/conv.py +0 -5
- femagtools/dxfsl/converter.py +92 -33
- femagtools/dxfsl/fslrenderer.py +14 -5
- femagtools/dxfsl/geom.py +245 -210
- femagtools/dxfsl/machine.py +166 -11
- femagtools/dxfsl/shape.py +46 -1
- femagtools/dxfsl/svgparser.py +1 -1
- femagtools/dxfsl/symmetry.py +115 -30
- femagtools/ecloss.py +13 -8
- femagtools/femag.py +61 -29
- femagtools/fsl.py +21 -6
- femagtools/machine/__init__.py +5 -4
- femagtools/machine/afpm.py +41 -15
- femagtools/machine/sizing.py +189 -11
- femagtools/machine/sm.py +5 -11
- femagtools/machine/utils.py +2 -2
- femagtools/mcv.py +2 -3
- femagtools/model.py +4 -3
- femagtools/parstudy.py +1 -1
- femagtools/plot/nc.py +2 -2
- femagtools/templates/afm_rotor.mako +4 -0
- femagtools/templates/prepare_thermal.mako +57 -54
- {femagtools-1.8.0.dist-info → femagtools-1.8.2.dist-info}/METADATA +1 -1
- {femagtools-1.8.0.dist-info → femagtools-1.8.2.dist-info}/RECORD +32 -32
- tests/test_mcv.py +1 -1
- {femagtools-1.8.0.dist-info → femagtools-1.8.2.dist-info}/LICENSE +0 -0
- {femagtools-1.8.0.dist-info → femagtools-1.8.2.dist-info}/WHEEL +0 -0
- {femagtools-1.8.0.dist-info → femagtools-1.8.2.dist-info}/entry_points.txt +0 -0
- {femagtools-1.8.0.dist-info → femagtools-1.8.2.dist-info}/top_level.txt +0 -0
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)
|
@@ -2753,7 +2791,7 @@ class Geometry(object):
|
|
2753
2791
|
intersection = False
|
2754
2792
|
inner_gap_list = []
|
2755
2793
|
for no_a in my_notouch:
|
2756
|
-
if no_a.
|
2794
|
+
if no_a.intersect_area(line):
|
2757
2795
|
intersection = True
|
2758
2796
|
logger.debug(" --> intersection with %s",
|
2759
2797
|
no_a.get_id())
|
@@ -2817,6 +2855,7 @@ class Geometry(object):
|
|
2817
2855
|
pts = self.split_and_get_intersect_points(line)
|
2818
2856
|
if len(pts) != 2:
|
2819
2857
|
logger.error("ERROR in create_aux_lines()")
|
2858
|
+
self.journal.put("warning", "Error while creating auxiliary lines")
|
2820
2859
|
logger.debug("Points: %s", pts)
|
2821
2860
|
logger.debug("Line: %s", line)
|
2822
2861
|
|
@@ -2957,12 +2996,22 @@ class Geometry(object):
|
|
2957
2996
|
self.sym_counterpart = 1
|
2958
2997
|
self.sym_part = 2
|
2959
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
|
+
|
2960
3005
|
def is_rotor(self):
|
3006
|
+
if self.sym_type != TYPE_UNDEFINED:
|
3007
|
+
return self.sym_type == TYPE_ROTOR
|
2961
3008
|
if self.sym_counterpart:
|
2962
3009
|
return self.sym_part < self.sym_counterpart
|
2963
3010
|
return False
|
2964
3011
|
|
2965
3012
|
def is_stator(self):
|
3013
|
+
if self.sym_type != TYPE_UNDEFINED:
|
3014
|
+
return self.sym_type == TYPE_STATOR
|
2966
3015
|
if self.sym_counterpart:
|
2967
3016
|
return self.sym_part > self.sym_counterpart
|
2968
3017
|
return False
|
@@ -3095,6 +3144,16 @@ class Geometry(object):
|
|
3095
3144
|
for e in elist:
|
3096
3145
|
e.init_attributes('lightblue', 'no_fsl')
|
3097
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
|
+
|
3098
3157
|
def search_subregions(self, startangle, endangle, EESM, single=False):
|
3099
3158
|
if self.is_stator():
|
3100
3159
|
self.search_stator_subregions(startangle,
|
@@ -3554,22 +3613,33 @@ class Geometry(object):
|
|
3554
3613
|
return
|
3555
3614
|
elements = []
|
3556
3615
|
for a in areas:
|
3557
|
-
elements += a.
|
3558
|
-
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
|
+
|
3559
3621
|
builder = AreaBuilder(geom=geom)
|
3560
|
-
if builder.create_area_groups(
|
3622
|
+
if builder.create_area_groups(mag_areas):
|
3561
3623
|
return # bad
|
3562
3624
|
group_list = builder.area_list
|
3563
|
-
|
3564
|
-
# self.areagroup_list = group_list
|
3625
|
+
|
3565
3626
|
for group in group_list:
|
3566
3627
|
if not group.is_magnet_rectangle():
|
3567
3628
|
logger.debug("Warning: group is not a rectangle")
|
3568
3629
|
group.set_type(AREA.TYPE_MAGNET_RECT)
|
3569
3630
|
phi = group.get_magnet_orientation()
|
3570
3631
|
for a in group.areas_of_group:
|
3571
|
-
logger.debug("Replace phi %s by %s", a.phi, phi)
|
3572
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___")
|
3573
3643
|
|
3574
3644
|
def search_unknown_subregions(self):
|
3575
3645
|
logger.debug("begin of search_unknown_subregions")
|
@@ -3613,7 +3683,7 @@ class Geometry(object):
|
|
3613
3683
|
def windings_in_the_middle(self, midangle):
|
3614
3684
|
wdg_areas = [a for a in self.list_of_areas()
|
3615
3685
|
if a.is_winding()]
|
3616
|
-
logger.
|
3686
|
+
logger.debug("%s windings in geom", len(wdg_areas))
|
3617
3687
|
for a in wdg_areas:
|
3618
3688
|
if greater(a.max_angle, midangle) and \
|
3619
3689
|
less(a.min_angle, midangle):
|
@@ -3635,16 +3705,25 @@ class Geometry(object):
|
|
3635
3705
|
area.mark_airgap_corners(start_cp, end_cp)
|
3636
3706
|
return
|
3637
3707
|
|
3638
|
-
def num_areas_of_type(self,
|
3708
|
+
def num_areas_of_type(self, types=()):
|
3639
3709
|
return len([area for area in self.list_of_areas()
|
3640
|
-
if area.
|
3710
|
+
if area.type in types])
|
3641
3711
|
|
3642
3712
|
def area_size_of_type(self, type):
|
3643
3713
|
return sum([area.surface for area in self.list_of_areas()
|
3644
3714
|
if area.is_type(type)])*1e-3
|
3645
3715
|
|
3646
3716
|
def num_of_windings(self):
|
3647
|
-
return self.num_areas_of_type(AREA.TYPE_WINDINGS)
|
3717
|
+
return self.num_areas_of_type((AREA.TYPE_WINDINGS,))
|
3718
|
+
|
3719
|
+
def num_of_irons(self):
|
3720
|
+
return self.num_areas_of_type((AREA.TYPE_IRON,
|
3721
|
+
AREA.TYPE_YOKE,
|
3722
|
+
AREA.TYPE_TOOTH,))
|
3723
|
+
|
3724
|
+
def num_of_magnets(self):
|
3725
|
+
return self.num_areas_of_type((AREA.TYPE_MAGNET_AIRGAP,
|
3726
|
+
AREA.TYPE_MAGNET_RECT,))
|
3648
3727
|
|
3649
3728
|
def area_close_to_endangle(self, type):
|
3650
3729
|
return len([area for area in self.list_of_areas()
|
@@ -4141,61 +4220,18 @@ class Geometry(object):
|
|
4141
4220
|
return True
|
4142
4221
|
return False
|
4143
4222
|
|
4144
|
-
def get_inner_airgap_line(self):
|
4145
|
-
logger.debug("begin of get_inner_airgap_line")
|
4146
|
-
|
4147
|
-
if not self.is_inner:
|
4148
|
-
logger.debug("end of get_inner_airgap_line: not inner")
|
4149
|
-
return [], []
|
4150
|
-
for a in self.area_list:
|
4151
|
-
logger.debug("%s", a)
|
4152
|
-
area = [a for a in self.area_list if a.close_to_ag_endcorner]
|
4153
|
-
if len(area) != 1:
|
4154
|
-
logger.debug("end of get_inner_airgap_line: %s areas found", len(area))
|
4155
|
-
return [], []
|
4156
|
-
|
4157
|
-
end_corner = self.end_corners[-1]
|
4158
|
-
logger.debug("END CORNER %s", end_corner)
|
4159
|
-
nodes = [n for n in area[0].list_of_nodes()]
|
4160
|
-
if not nodes:
|
4161
|
-
logger.debug("end of get_inner_airgap_line: no nodes found")
|
4162
|
-
return [], []
|
4163
|
-
n1 = nodes[0]
|
4164
|
-
if points_are_close(end_corner, n1):
|
4165
|
-
n2 = nodes[-1]
|
4166
|
-
else:
|
4167
|
-
n2 = n1
|
4168
|
-
for n1 in nodes[1:]:
|
4169
|
-
if points_are_close(end_corner, n1):
|
4170
|
-
break
|
4171
|
-
n2 = n1
|
4172
|
-
|
4173
|
-
if not points_are_close(end_corner, n1):
|
4174
|
-
logger.debug("end of get_inner_airgap_line: not close to endcorner")
|
4175
|
-
return [], []
|
4176
|
-
|
4177
|
-
start_corner = self.start_corners[-1]
|
4178
|
-
|
4179
|
-
logger.debug("EDGE FOUND: %s - %s", n1, n2)
|
4180
|
-
nodes = [n1, n2]
|
4181
|
-
info = self.get_edge_info(n1, n2)
|
4182
|
-
elements = [info.get('element', None)]
|
4183
|
-
while not points_are_close(start_corner, n2):
|
4184
|
-
info = self.next_edge_lefthand_side(info)
|
4185
|
-
if not info:
|
4186
|
-
return []
|
4187
|
-
n2 = info['n2']
|
4188
|
-
nodes.append(n2)
|
4189
|
-
elements.append(info.get('element', None))
|
4190
|
-
|
4191
|
-
logger.debug("end of get_inner_airgap_line #%s", len(nodes))
|
4192
|
-
return nodes, elements
|
4193
|
-
|
4194
4223
|
def create_inner_corner_areas(self, startangle, endangle):
|
4195
|
-
self
|
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))
|
4196
4230
|
|
4197
4231
|
builder = AreaBuilder(geom=self)
|
4198
|
-
builder.
|
4232
|
+
rslt = builder.close_outer_winding_areas()
|
4233
|
+
logger.debug("end close_outer_winding_areas (%s)", rslt)
|
4234
|
+
return rslt
|
4199
4235
|
|
4200
4236
|
def repair_border_line(self, nodes):
|
4201
4237
|
logger.debug("begin repair_border_line")
|
@@ -4206,9 +4242,9 @@ class Geometry(object):
|
|
4206
4242
|
if not ok1: # fatal => ignore
|
4207
4243
|
logger.debug("end repair_border_line: missing point %s", n1)
|
4208
4244
|
return False
|
4209
|
-
|
4210
|
-
if not
|
4211
|
-
logger.debug("end repair_border_line: missing point %s",
|
4245
|
+
d2, n2, ok2 = nodes[-1]
|
4246
|
+
if not ok2: # fatal => ignore
|
4247
|
+
logger.debug("end repair_border_line: missing point %s", n2)
|
4212
4248
|
return False
|
4213
4249
|
|
4214
4250
|
remove_n1 = None
|
@@ -4240,89 +4276,132 @@ class Geometry(object):
|
|
4240
4276
|
logger.debug("end repair_border_line")
|
4241
4277
|
return True
|
4242
4278
|
|
4243
|
-
def
|
4279
|
+
def create_boundary_nodes(self,
|
4244
4280
|
center,
|
4245
4281
|
startangle,
|
4246
4282
|
endangle,
|
4247
4283
|
rtol=None, atol=None):
|
4284
|
+
logger.debug("begin of create_boundary_nodes")
|
4248
4285
|
if not rtol:
|
4249
|
-
rtol = 1e-
|
4286
|
+
rtol = 1e-3
|
4250
4287
|
if not atol:
|
4251
4288
|
atol = 1e-3
|
4252
4289
|
|
4253
|
-
|
4254
|
-
|
4255
|
-
|
4256
|
-
|
4257
|
-
|
4258
|
-
|
4259
|
-
|
4260
|
-
|
4261
|
-
def miss_nodelist(src_nodelist, dest_nodelist):
|
4262
|
-
nlist = []
|
4263
|
-
for src_n in src_nodelist:
|
4264
|
-
ok = False
|
4265
|
-
for dest_n in dest_nodelist:
|
4266
|
-
if points_are_close(src_n, dest_n, rtol=rtol, atol=atol):
|
4267
|
-
ok = True
|
4268
|
-
break
|
4269
|
-
if not ok:
|
4270
|
-
nlist.append(src_n)
|
4271
|
-
return nlist
|
4272
|
-
|
4273
|
-
logger.debug("Begin with Nodes Start=%s, End=%s", len(start_nodes), len(end_nodes))
|
4274
|
-
|
4275
|
-
missing_end_nodes = miss_nodelist(start_rot_nodes, end_nodes)
|
4276
|
-
missing_start_nodes = miss_nodelist(end_rot_nodes, start_nodes)
|
4277
|
-
|
4278
|
-
if missing_start_nodes:
|
4279
|
-
logger.debug("%s missing start nodes", len(missing_start_nodes))
|
4280
|
-
start_nodes = [(distance(center, n), n, True) for n in start_nodes]
|
4281
|
-
for n in missing_start_nodes:
|
4282
|
-
start_nodes.append((distance(center, n), n, False))
|
4283
|
-
start_nodes.sort()
|
4284
|
-
if not self.repair_border_line(start_nodes):
|
4285
|
-
logger.debug("end of create_boundery_nodes (failed)")
|
4286
|
-
return
|
4287
|
-
else:
|
4288
|
-
start_nodes = [(distance(center, n), n, True) for n in start_nodes]
|
4289
|
-
start_nodes.sort()
|
4290
|
-
|
4291
|
-
if missing_end_nodes:
|
4292
|
-
logger.debug("%s missing end nodes", len(missing_end_nodes))
|
4293
|
-
end_nodes = [(distance(center, n), n, True) for n in end_nodes]
|
4294
|
-
for n in missing_end_nodes:
|
4295
|
-
end_nodes.append((distance(center, n), n, False))
|
4296
|
-
end_nodes.sort()
|
4297
|
-
if not self.repair_border_line(end_nodes):
|
4298
|
-
logger.debug("end of create_boundery_nodes (failed)")
|
4299
|
-
return
|
4300
|
-
else:
|
4301
|
-
end_nodes = [(distance(center, n), n, True) for n in end_nodes]
|
4302
|
-
end_nodes.sort()
|
4290
|
+
def check_line(nlist):
|
4291
|
+
d, n1, b = nlist[0]
|
4292
|
+
for d, n2, b in nlist[1:]:
|
4293
|
+
if not self.get_edge_element(n1, n2):
|
4294
|
+
return False
|
4295
|
+
n1 = n2
|
4296
|
+
return True
|
4303
4297
|
|
4304
|
-
start_nodes = [(distance(center, n), n)
|
4298
|
+
start_nodes = [(distance(center, n), n, True)
|
4305
4299
|
for n in self.angle_nodes(center, startangle, rtol, atol)]
|
4306
4300
|
start_nodes.sort()
|
4307
|
-
|
4301
|
+
d_start1, n, b = start_nodes[0]
|
4302
|
+
if not points_are_close(self.start_corners[0], n):
|
4303
|
+
logger.warning("end of create_boundary_nodes: corner missing in start boundary")
|
4304
|
+
return False
|
4305
|
+
d_start2, n, b = start_nodes[-1]
|
4306
|
+
if not points_are_close(self.start_corners[-1], n):
|
4307
|
+
logger.warning("end of create_boundary_nodes: corner missing in start boundary")
|
4308
|
+
return False
|
4309
|
+
if not check_line(start_nodes):
|
4310
|
+
logger.warning("end of create_boundary_nodes: bad start boundary")
|
4311
|
+
return False
|
4312
|
+
|
4313
|
+
logger.debug("Start Nodes")
|
4314
|
+
[logger.debug(" --> %s", x) for x in start_nodes]
|
4315
|
+
|
4316
|
+
end_nodes = [(distance(center, n), n, True)
|
4308
4317
|
for n in self.angle_nodes(center, endangle, rtol, atol)]
|
4309
4318
|
end_nodes.sort()
|
4319
|
+
d_end1, n, b = end_nodes[0]
|
4320
|
+
if not points_are_close(self.end_corners[0], n):
|
4321
|
+
logger.warning("end of create_boundary_nodes: corner missing in end boundary")
|
4322
|
+
return False
|
4323
|
+
d_end2, n, b = end_nodes[-1]
|
4324
|
+
if not points_are_close(self.end_corners[-1], n):
|
4325
|
+
logger.warning("end of create_boundary_nodes: corner missing in end boundary")
|
4326
|
+
return False
|
4327
|
+
if not check_line(end_nodes):
|
4328
|
+
logger.warning("end of create_boundary_nodes: bad end boundary")
|
4329
|
+
return False
|
4310
4330
|
|
4311
|
-
logger.debug("End
|
4331
|
+
logger.debug("End Nodes")
|
4332
|
+
[logger.debug(" --> %s", x) for x in end_nodes]
|
4312
4333
|
|
4313
|
-
|
4314
|
-
|
4334
|
+
logger.debug("Lower Corners: %s <> %s", d_start1, d_end1)
|
4335
|
+
if not np.isclose(d_start1, d_end1, rtol=self.rtol, atol=self.atol):
|
4336
|
+
logger.warning("end of create_boundary_nodes: corners dont match")
|
4337
|
+
return False
|
4315
4338
|
|
4316
|
-
|
4317
|
-
|
4318
|
-
|
4319
|
-
|
4320
|
-
for d, node in end_nodes:
|
4321
|
-
self.set_point_of_node(node, start_rot_nodes[i])
|
4322
|
-
i += 1
|
4339
|
+
logger.debug("Upper Corners: %s <> %s", d_start2, d_end2)
|
4340
|
+
if not np.isclose(d_start2, d_end2, rtol=self.rtol, atol=self.atol):
|
4341
|
+
logger.warning("end of create_boundary_nodes: corners dont match")
|
4342
|
+
return False
|
4323
4343
|
|
4324
|
-
|
4325
|
-
|
4344
|
+
if len(start_nodes) == 2 and len(end_nodes) == 2:
|
4345
|
+
logger.debug("end of create_boundary_nodes: only corners available")
|
4346
|
+
return False # ok
|
4347
|
+
|
4348
|
+
def node_distance_list(nodelist1, nodelist2):
|
4349
|
+
distlist = []
|
4350
|
+
i1 = 0
|
4351
|
+
i2 = 0
|
4352
|
+
while i1 < len(nodelist1) and i2 < len(nodelist2):
|
4353
|
+
d1, n1, b1 = nodelist1[i1]
|
4354
|
+
d2, n2, b2 = nodelist2[i2]
|
4355
|
+
if np.isclose(d1, d2, rtol=self.rtol, atol=self.atol):
|
4356
|
+
distlist.append((d1, True, True))
|
4357
|
+
i1 += 1
|
4358
|
+
i2 += 1
|
4359
|
+
elif d1 > d2:
|
4360
|
+
distlist.append((d2, False, True))
|
4361
|
+
i2 += 1
|
4362
|
+
else:
|
4363
|
+
distlist.append((d1, True, False))
|
4364
|
+
i1 += 1
|
4365
|
+
if not i1 == len(nodelist1) and i2 == len(nodelist2):
|
4366
|
+
return []
|
4367
|
+
return distlist
|
4368
|
+
|
4369
|
+
distance_list = node_distance_list(start_nodes, end_nodes)
|
4370
|
+
[logger.debug("distance: %s, (%s, %s)", d, b1, b2)
|
4371
|
+
for d, b1, b2 in distance_list]
|
4372
|
+
|
4373
|
+
diff = len(distance_list) - len(start_nodes)
|
4374
|
+
done = False
|
4375
|
+
if not diff == 0:
|
4376
|
+
logger.debug("%s missing start nodes", diff)
|
4377
|
+
done = True
|
4378
|
+
for d, in_start, in_end in distance_list:
|
4379
|
+
if not in_start:
|
4380
|
+
p = point(self.center, d, startangle)
|
4381
|
+
start_nodes.append((d, p, False))
|
4382
|
+
start_nodes.sort()
|
4383
|
+
assert(len(start_nodes) == len(distance_list))
|
4384
|
+
if not self.repair_border_line(start_nodes):
|
4385
|
+
logger.debug("end of create_boundary_nodes (failed)")
|
4386
|
+
return False
|
4387
|
+
|
4388
|
+
diff = len(distance_list) - len(end_nodes)
|
4389
|
+
if not diff == 0:
|
4390
|
+
logger.debug("%s missing end nodes", diff)
|
4391
|
+
done = True
|
4392
|
+
for d, in_start, in_end in distance_list:
|
4393
|
+
if not in_end:
|
4394
|
+
p = point(self.center, d, endangle)
|
4395
|
+
end_nodes.append((d, p, False))
|
4396
|
+
end_nodes.sort()
|
4397
|
+
assert(len(end_nodes) == len(distance_list))
|
4398
|
+
|
4399
|
+
if not self.repair_border_line(end_nodes):
|
4400
|
+
logger.debug("end of create_boundary_nodes (failed)")
|
4401
|
+
return False
|
4402
|
+
|
4403
|
+
logger.debug("end of create_boundary_nodes")
|
4404
|
+
return done
|
4326
4405
|
|
4327
4406
|
def set_point_of_node(self, node, p):
|
4328
4407
|
if isinstance(node, list):
|
@@ -4354,78 +4433,34 @@ class Geometry(object):
|
|
4354
4433
|
points += pts
|
4355
4434
|
return points
|
4356
4435
|
|
4357
|
-
def
|
4358
|
-
|
4359
|
-
|
4360
|
-
|
4361
|
-
return
|
4362
|
-
logger.debug("*** Corner Auxiliary Areas ***")
|
4363
|
-
airgap_line, airgap_el = self.get_inner_airgap_line()
|
4364
|
-
if not airgap_el:
|
4365
|
-
logger.debug("no airgapline found")
|
4366
|
-
return
|
4367
|
-
|
4368
|
-
logger.debug("airgapline found !!")
|
4369
|
-
airgap_nodes = [n for n in airgap_line[1:]]
|
4370
|
-
del airgap_nodes[-1]
|
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)
|
4371
4440
|
|
4372
|
-
|
4373
|
-
|
4374
|
-
|
4375
|
-
|
4376
|
-
color='red',
|
4377
|
-
linestyle='dotted')
|
4378
|
-
|
4379
|
-
start_cp = start_line.node2(ndec)
|
4380
|
-
for n in airgap_nodes:
|
4381
|
-
ag_line = Line(Element(start=start_cp, end=n))
|
4382
|
-
points = self.get_intersection_points(airgap_el, ag_line, n)
|
4383
|
-
if not points: # no intersection
|
4384
|
-
d = distance(self.center, n)
|
4385
|
-
if np.isclose(d, self.max_radius):
|
4386
|
-
self.add_arc(start_cp, n, self.center, self.max_radius,
|
4387
|
-
color='red',
|
4388
|
-
linestyle='dotted')
|
4389
|
-
else:
|
4390
|
-
self.add_line(start_cp, n,
|
4391
|
-
color='red',
|
4392
|
-
linestyle='dotted')
|
4393
|
-
self.add_element(start_line,
|
4394
|
-
rtol=self.rtol,
|
4395
|
-
atol=self.atol)
|
4396
|
-
self.create_and_append_area(start_cp, n)
|
4397
|
-
self.start_corners = self.get_corner_nodes(self.center,
|
4398
|
-
0.0)
|
4399
|
-
break
|
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)
|
4400
4445
|
|
4401
|
-
|
4402
|
-
|
4403
|
-
|
4404
|
-
|
4405
|
-
|
4406
|
-
|
4407
|
-
|
4408
|
-
|
4409
|
-
|
4410
|
-
|
4411
|
-
|
4412
|
-
|
4413
|
-
|
4414
|
-
|
4415
|
-
|
4416
|
-
|
4417
|
-
|
4418
|
-
|
4419
|
-
self.add_line(end_cp, n,
|
4420
|
-
color='red',
|
4421
|
-
linestyle='dotted')
|
4422
|
-
self.add_element(end_line,
|
4423
|
-
rtol=self.rtol,
|
4424
|
-
atol=self.atol)
|
4425
|
-
self.create_and_append_area(n, end_cp)
|
4426
|
-
self.end_corners = self.get_corner_nodes(self.center,
|
4427
|
-
self.alfa)
|
4428
|
-
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")
|
4429
4464
|
|
4430
4465
|
def print_nodes(self):
|
4431
4466
|
print("=== List of Nodes ({}) ===".format(self.number_of_nodes()))
|