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.
- femagtools/__init__.py +1 -1
- femagtools/dxfsl/area.py +110 -1
- femagtools/dxfsl/areabuilder.py +93 -45
- femagtools/dxfsl/conv.py +5 -0
- femagtools/dxfsl/converter.py +85 -27
- femagtools/dxfsl/fslrenderer.py +5 -4
- femagtools/dxfsl/functions.py +14 -6
- femagtools/dxfsl/geom.py +135 -149
- femagtools/dxfsl/journal.py +1 -1
- femagtools/dxfsl/machine.py +161 -9
- femagtools/dxfsl/shape.py +46 -1
- femagtools/dxfsl/svgparser.py +1 -1
- femagtools/dxfsl/symmetry.py +143 -38
- femagtools/femag.py +64 -61
- femagtools/fsl.py +15 -12
- femagtools/isa7.py +3 -2
- femagtools/machine/__init__.py +5 -4
- femagtools/machine/afpm.py +79 -33
- femagtools/machine/effloss.py +29 -18
- femagtools/machine/sizing.py +192 -13
- femagtools/machine/sm.py +34 -36
- femagtools/machine/utils.py +2 -2
- femagtools/mcv.py +58 -29
- femagtools/model.py +4 -3
- femagtools/multiproc.py +79 -80
- femagtools/parstudy.py +11 -5
- femagtools/plot/nc.py +2 -2
- femagtools/semi_fea.py +108 -0
- femagtools/templates/basic_modpar.mako +0 -3
- femagtools/templates/fe-contr.mako +18 -18
- femagtools/templates/ld_lq_fast.mako +3 -0
- femagtools/templates/mult_cal_fast.mako +3 -0
- femagtools/templates/pm_sym_f_cur.mako +4 -1
- femagtools/templates/pm_sym_fast.mako +3 -0
- femagtools/templates/pm_sym_loss.mako +3 -0
- femagtools/templates/psd_psq_fast.mako +3 -0
- femagtools/templates/torq_calc.mako +3 -0
- femagtools/tks.py +23 -20
- femagtools/zmq.py +213 -0
- {femagtools-1.8.1.dist-info → femagtools-1.8.3.dist-info}/METADATA +3 -3
- {femagtools-1.8.1.dist-info → femagtools-1.8.3.dist-info}/RECORD +49 -47
- {femagtools-1.8.1.dist-info → femagtools-1.8.3.dist-info}/WHEEL +1 -1
- tests/test_afpm.py +15 -6
- tests/test_femag.py +1 -1
- tests/test_fsl.py +4 -4
- tests/test_mcv.py +21 -15
- {femagtools-1.8.1.dist-info → femagtools-1.8.3.dist-info}/LICENSE +0 -0
- {femagtools-1.8.1.dist-info → femagtools-1.8.3.dist-info}/entry_points.txt +0 -0
- {femagtools-1.8.1.dist-info → femagtools-1.8.3.dist-info}/top_level.txt +0 -0
femagtools/__init__.py
CHANGED
femagtools/dxfsl/area.py
CHANGED
@@ -12,6 +12,7 @@ import numpy as np
|
|
12
12
|
import networkx as nx
|
13
13
|
import logging
|
14
14
|
from .functions import less_equal, less, greater_equal, greater
|
15
|
+
from .functions import greater_angle, less_angle
|
15
16
|
from .functions import distance, alpha_angle, alpha_line, min_angle, max_angle
|
16
17
|
from .functions import point, line_m, line_n, intersect_point, points_are_close
|
17
18
|
from .functions import middle_angle, part_of_circle, is_same_angle
|
@@ -75,6 +76,10 @@ class Area(object):
|
|
75
76
|
self.start = 0.0
|
76
77
|
self.sym_startangle = 0.0
|
77
78
|
self.sym_endangle = 0.0
|
79
|
+
self.sym_upper_left_dist = None
|
80
|
+
self.sym_upper_right_dist = None
|
81
|
+
self.sym_lower_left_dist = None
|
82
|
+
self.sym_lower_right_dist = None
|
78
83
|
self.sym_type = 0
|
79
84
|
self.symmetry = 0
|
80
85
|
self.sym_tolerance = sym_tolerance
|
@@ -100,6 +105,9 @@ class Area(object):
|
|
100
105
|
def elements(self):
|
101
106
|
return self.area
|
102
107
|
|
108
|
+
def copy_of_elements(self):
|
109
|
+
return [e.clone() for e in self.elements() if e]
|
110
|
+
|
103
111
|
def list_of_nodes(self):
|
104
112
|
if len(self.area) < 1:
|
105
113
|
return
|
@@ -671,6 +679,66 @@ class Area(object):
|
|
671
679
|
return True
|
672
680
|
return False
|
673
681
|
|
682
|
+
def set_symmetry_parameter(self, center):
|
683
|
+
all_list = [(distance(center, n), alpha_line(center, n))
|
684
|
+
for n in self.list_of_nodes()]
|
685
|
+
mid = middle_angle(self.min_angle, self.max_angle)
|
686
|
+
left_list = [(d, a) for d, a in all_list if greater_angle(a, mid)]
|
687
|
+
right_list = [(d, a) for d, a in all_list if less_angle(a, mid)]
|
688
|
+
left_list.sort()
|
689
|
+
right_list.sort()
|
690
|
+
|
691
|
+
if left_list:
|
692
|
+
l_low_d, l_low_a = left_list[0]
|
693
|
+
l_up_d, l_up_a = left_list[-1]
|
694
|
+
else:
|
695
|
+
l_low_d = self.min_dist
|
696
|
+
l_up_d = self.max_dist
|
697
|
+
if right_list:
|
698
|
+
r_low_d, r_low_a = right_list[0]
|
699
|
+
r_up_d, r_up_a = right_list[-1]
|
700
|
+
else:
|
701
|
+
r_low_d = self.min_dist
|
702
|
+
r_up_d = self.max_dist
|
703
|
+
self.sym_upper_left_dist = l_up_d
|
704
|
+
self.sym_upper_right_dist = r_up_d
|
705
|
+
self.sym_lower_left_dist = l_low_d
|
706
|
+
self.sym_lower_right_dist = r_low_d
|
707
|
+
|
708
|
+
def is_symmetry_equal(self, area):
|
709
|
+
logger.debug("check area %s -- %s", self.get_id(), area.get_id())
|
710
|
+
|
711
|
+
bad = False
|
712
|
+
if not np.isclose(self.sym_lower_left_dist, area.sym_lower_left_dist,
|
713
|
+
rtol=5e-1, atol=5e-1):
|
714
|
+
logger.debug("Lower left: %s != %s",
|
715
|
+
self.sym_lower_left_dist,
|
716
|
+
area.sym_lower_left_dist)
|
717
|
+
bad = True
|
718
|
+
|
719
|
+
if not np.isclose(self.sym_lower_right_dist, area.sym_lower_right_dist,
|
720
|
+
rtol=5e-1, atol=5e-1):
|
721
|
+
logger.debug("Lower right: %s != %s",
|
722
|
+
self.sym_lower_right_dist,
|
723
|
+
area.sym_lower_right_dist)
|
724
|
+
bad = True
|
725
|
+
|
726
|
+
if not np.isclose(self.sym_upper_left_dist, area.sym_upper_left_dist,
|
727
|
+
rtol=5e-1, atol=5e-1):
|
728
|
+
logger.debug("Upper left: %s != %s",
|
729
|
+
self.sym_upper_left_dist,
|
730
|
+
area.sym_upper_left_dist)
|
731
|
+
bad = True
|
732
|
+
|
733
|
+
if not np.isclose(self.sym_upper_right_dist, area.sym_upper_right_dist,
|
734
|
+
rtol=5e-1, atol=5e-1):
|
735
|
+
logger.debug("Upper right: %s != %s",
|
736
|
+
self.sym_upper_right_dist,
|
737
|
+
area.sym_upper_right_dist)
|
738
|
+
bad = True
|
739
|
+
|
740
|
+
return not bad
|
741
|
+
|
674
742
|
def increment(self, a):
|
675
743
|
if self.is_identical(a):
|
676
744
|
return
|
@@ -1208,6 +1276,7 @@ class Area(object):
|
|
1208
1276
|
|
1209
1277
|
angles.sort(reverse=True)
|
1210
1278
|
# calculate orientation (no rectangle check)
|
1279
|
+
|
1211
1280
|
l, alpha = angles[0]
|
1212
1281
|
phi = normalise_angle(alpha + np.pi/2)
|
1213
1282
|
logger.debug("alpha = %s, phi = %s", alpha, phi)
|
@@ -1216,9 +1285,13 @@ class Area(object):
|
|
1216
1285
|
angle = alpha_angle(mid, phi)
|
1217
1286
|
logger.debug("phi=%s, mid=%s, angle=%s", phi, mid, angle)
|
1218
1287
|
|
1219
|
-
if
|
1288
|
+
if np.isclose(mid, alpha, rtol=1e-3, atol=1e-3):
|
1289
|
+
phi = mid
|
1290
|
+
logger.debug("correction of phi=%s", phi)
|
1291
|
+
elif greater(angle, np.pi * 0.5, rtol=1e-5) and \
|
1220
1292
|
less(angle, np.pi * 1.5, rtol=1e-5):
|
1221
1293
|
phi = normalise_angle(phi + np.pi)
|
1294
|
+
logger.debug("correction of phi=%s", phi)
|
1222
1295
|
|
1223
1296
|
logger.debug("phi of magnet %s is %s", self.identifier(), phi)
|
1224
1297
|
return phi
|
@@ -1321,6 +1394,32 @@ class Area(object):
|
|
1321
1394
|
return np.isclose(angle, border_angle,
|
1322
1395
|
rtol=1e-03, atol=1e-03)
|
1323
1396
|
|
1397
|
+
def set_subregion_parameters(self,
|
1398
|
+
is_inner,
|
1399
|
+
min_radius,
|
1400
|
+
max_radius,
|
1401
|
+
startangle,
|
1402
|
+
endangle):
|
1403
|
+
ag_delta = (max_radius - min_radius) / 500.0
|
1404
|
+
if is_inner:
|
1405
|
+
self.close_to_ag = greater_equal(self.max_dist + ag_delta, max_radius)
|
1406
|
+
close_to_opposition = np.isclose(min_radius, self.min_dist)
|
1407
|
+
airgap_radius = max_radius
|
1408
|
+
opposite_radius = min_radius
|
1409
|
+
else:
|
1410
|
+
self.close_to_ag = less_equal(self.min_dist - ag_delta, min_radius)
|
1411
|
+
close_to_opposition = np.isclose(max_radius, self.max_dist)
|
1412
|
+
airgap_radius = min_radius
|
1413
|
+
opposite_radius = max_radius
|
1414
|
+
|
1415
|
+
airgap_toleranz = (self.max_dist - self.min_dist) / 50.0 # 2%
|
1416
|
+
|
1417
|
+
self.close_to_startangle = np.isclose(self.min_angle, startangle,
|
1418
|
+
1e-04, 1e-04)
|
1419
|
+
self.close_to_endangle = np.isclose(self.max_angle, endangle,
|
1420
|
+
1e-04, 1e-04)
|
1421
|
+
self.surface = self.area_size()
|
1422
|
+
|
1324
1423
|
def mark_stator_subregions(self,
|
1325
1424
|
is_inner,
|
1326
1425
|
stator_size,
|
@@ -1791,6 +1890,16 @@ class Area(object):
|
|
1791
1890
|
for i in a.nested_areas_inside():
|
1792
1891
|
yield i
|
1793
1892
|
|
1893
|
+
def mirror_area(self, center, axis_m, axis_n):
|
1894
|
+
elements = []
|
1895
|
+
for e in self.area:
|
1896
|
+
el = e.mirror_shape(center, axis_m, axis_n)
|
1897
|
+
if el:
|
1898
|
+
elements.append(el)
|
1899
|
+
area = Area(elements, center, 0.0)
|
1900
|
+
area.type = self.type
|
1901
|
+
return area
|
1902
|
+
|
1794
1903
|
def __str__(self):
|
1795
1904
|
return "Area {}\n".format(self.id) + \
|
1796
1905
|
"distance...............: from {} to {}\n".\
|
femagtools/dxfsl/areabuilder.py
CHANGED
@@ -338,7 +338,7 @@ class EdgeInfo(object):
|
|
338
338
|
return True # two lines
|
339
339
|
|
340
340
|
def arc_line_direction_lefthand(self, start_edge, line_edge, builder):
|
341
|
-
logger.
|
341
|
+
logger.debug("begin of arc_line_direction_lefthand")
|
342
342
|
if not self.is_arc():
|
343
343
|
logger.critical("FATAL: unexpected %s at position %s", self.classname(), self.n1)
|
344
344
|
sys.exit(1)
|
@@ -630,7 +630,7 @@ class AreaBuilder(object):
|
|
630
630
|
logger.debug("begin of create_inner_corner_auxiliary_areas")
|
631
631
|
if not self.geom.is_inner:
|
632
632
|
logger.debug("end of create_inner_corner_auxiliary_areas: not inner")
|
633
|
-
return
|
633
|
+
return False
|
634
634
|
|
635
635
|
self.set_edge_attributes()
|
636
636
|
|
@@ -647,17 +647,18 @@ class AreaBuilder(object):
|
|
647
647
|
|
648
648
|
if start_exists and end_exists:
|
649
649
|
logger.debug("end of create_inner_corner_auxiliary_areas: no aktion")
|
650
|
-
return
|
650
|
+
return False
|
651
651
|
|
652
652
|
airgap_line, airgap_el = self.get_inner_airgap_line()
|
653
653
|
if not airgap_el:
|
654
654
|
logger.debug("end of create_inner_corner_auxiliary_areas: no airgapline found")
|
655
|
-
return
|
655
|
+
return False
|
656
656
|
|
657
657
|
logger.debug("airgapline found !!")
|
658
658
|
airgap_nodes = [n for n in airgap_line[1:]]
|
659
659
|
del airgap_nodes[-1]
|
660
660
|
|
661
|
+
created = False
|
661
662
|
if not start_exists:
|
662
663
|
cp = self.geom.start_corners[-1]
|
663
664
|
logger.debug("Start Corner: %s -- %s", cp, start_cp)
|
@@ -683,6 +684,7 @@ class AreaBuilder(object):
|
|
683
684
|
n,
|
684
685
|
color='red',
|
685
686
|
linestyle='dotted')
|
687
|
+
created = True
|
686
688
|
start_node = self.geom.get_node(start_cp)
|
687
689
|
self.geom.add_edge(cp, start_node, start_line)
|
688
690
|
result = self.get_new_area(start_node, n)
|
@@ -715,6 +717,7 @@ class AreaBuilder(object):
|
|
715
717
|
self.geom.add_line(end_cp, n,
|
716
718
|
color='red',
|
717
719
|
linestyle='dotted')
|
720
|
+
created = True
|
718
721
|
end_node = self.geom.get_node(end_cp)
|
719
722
|
self.geom.add_edge(cp, end_node, end_line)
|
720
723
|
result = self.get_new_area(n, end_node)
|
@@ -725,81 +728,126 @@ class AreaBuilder(object):
|
|
725
728
|
break
|
726
729
|
|
727
730
|
logger.debug("end of create_inner_corner_auxiliary_areas")
|
731
|
+
return created
|
728
732
|
|
729
|
-
def
|
730
|
-
logger.debug("
|
731
|
-
assert(self.geom.is_inner)
|
732
|
-
assert(self.geom.area_list)
|
733
|
-
|
734
|
-
area = [a for a in self.geom.area_list if a.close_to_ag_endcorner]
|
735
|
-
if len(area) != 1:
|
736
|
-
logger.debug("end of get_inner_airgap_line: %s areas found", len(area))
|
737
|
-
return [], []
|
733
|
+
def get_airgap_line(self, start_node, end_node, area):
|
734
|
+
logger.debug("get_airgap_line")
|
738
735
|
|
739
|
-
|
740
|
-
logger.debug("END CORNER %s", end_corner)
|
736
|
+
self.set_edge_attributes()
|
741
737
|
|
742
|
-
nodes = [n for n in area
|
738
|
+
nodes = [n for n in area.list_of_nodes()]
|
743
739
|
if not nodes:
|
744
|
-
logger.debug("end of
|
740
|
+
logger.debug("end of get_airgap_line: no nodes found")
|
745
741
|
return [], []
|
746
742
|
|
747
743
|
n1 = nodes[0]
|
748
|
-
if points_are_close(
|
744
|
+
if points_are_close(start_node, n1):
|
749
745
|
n2 = nodes[-1]
|
750
746
|
else:
|
751
747
|
n2 = n1
|
752
748
|
for n1 in nodes[1:]:
|
753
|
-
if points_are_close(
|
749
|
+
if points_are_close(start_node, n1):
|
754
750
|
break
|
755
751
|
n2 = n1
|
756
752
|
|
757
|
-
if not points_are_close(
|
758
|
-
logger.debug("end of
|
753
|
+
if not points_are_close(start_node, n1):
|
754
|
+
logger.debug("end of get_airgap_line: not close to start-node")
|
759
755
|
return [], []
|
760
756
|
|
761
|
-
|
762
|
-
logger.debug("START CORNER %s", end_corner)
|
763
|
-
|
764
|
-
logger.debug("EDGE FOUND: %s - %s", n1, n2)
|
757
|
+
logger.debug("START EDGE FOUND: %s - %s", n1, n2)
|
765
758
|
nodes = [n1, n2]
|
766
759
|
info = self.get_edge_info(n1, n2)
|
767
760
|
elements = [info.element]
|
768
761
|
|
769
|
-
while not points_are_close(
|
762
|
+
while not points_are_close(end_node, n2):
|
770
763
|
info.set_start_angle()
|
771
764
|
info = self.next_edge_lefthand_side(info)
|
772
765
|
if not info: # bad
|
773
|
-
return []
|
766
|
+
return [], []
|
774
767
|
n2 = info.n2
|
775
768
|
nodes.append(n2)
|
776
769
|
elements.append(info.element)
|
777
770
|
|
778
|
-
logger.debug("end of
|
771
|
+
logger.debug("end of get_airgap_line #%s", len(nodes))
|
779
772
|
return nodes, elements
|
780
773
|
|
781
|
-
def
|
782
|
-
logger.debug("begin of
|
774
|
+
def get_inner_airgap_line(self):
|
775
|
+
logger.debug("begin of get_inner_airgap_line")
|
776
|
+
assert(self.geom.is_inner)
|
783
777
|
assert(self.geom.area_list)
|
784
778
|
|
785
|
-
|
779
|
+
area = [a for a in self.geom.area_list if a.close_to_ag_endcorner]
|
780
|
+
if len(area) != 1:
|
781
|
+
logger.debug("end of get_inner_airgap_line: %s areas found", len(area))
|
782
|
+
return [], []
|
786
783
|
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
|
784
|
+
start_node = self.geom.end_corners[-1]
|
785
|
+
logger.debug("START NODE %s", start_node)
|
786
|
+
end_node = self.geom.start_corners[-1]
|
787
|
+
logger.debug("END NODE %s", end_node)
|
791
788
|
|
792
|
-
|
793
|
-
info.set_start_angle()
|
794
|
-
info = self.next_edge_lefthand_side(info)
|
795
|
-
if not info: # bad
|
796
|
-
return []
|
797
|
-
n2 = info.n2
|
798
|
-
nodes.append(n2)
|
799
|
-
elements.append(info.element)
|
789
|
+
return self.get_airgap_line(start_node, end_node, area[0])
|
800
790
|
|
801
|
-
|
802
|
-
|
791
|
+
def close_outer_winding_areas(self):
|
792
|
+
logger.debug("close_outer_winding_areas")
|
793
|
+
|
794
|
+
airgap_line, airgap_el = self.get_outer_airgap_line()
|
795
|
+
logger.debug("Outer Airgap with %s Nodes", len(airgap_line))
|
796
|
+
|
797
|
+
if len(airgap_line) < 5:
|
798
|
+
return False
|
799
|
+
|
800
|
+
n1 = None
|
801
|
+
dist_n1 = 0.0
|
802
|
+
|
803
|
+
e_prev = None
|
804
|
+
n_prev = airgap_line[0]
|
805
|
+
dist_prev = distance(self.geom.center, n_prev)
|
806
|
+
alpha_prev = alpha_line(self.geom.center, n_prev)
|
807
|
+
alpha_start = alpha_prev
|
808
|
+
|
809
|
+
lines_created = 0
|
810
|
+
for n in airgap_line[1:]:
|
811
|
+
dist = distance(self.geom.center, n)
|
812
|
+
alpha = alpha_line(self.geom.center, n)
|
813
|
+
if not n1:
|
814
|
+
if dist > dist_prev and alpha < alpha_prev:
|
815
|
+
n1 = n_prev
|
816
|
+
dist_n1 = dist_prev
|
817
|
+
else:
|
818
|
+
if np.isclose(dist_n1, dist, rtol=1e-3, atol=1e-3):
|
819
|
+
line = Line(Element(start=n1, end=n))
|
820
|
+
if e_prev.intersect_line(line):
|
821
|
+
logger.debug("___LINE NOT POSSIBLE___")
|
822
|
+
else:
|
823
|
+
self.geom.add_line(n1, n, color='red')
|
824
|
+
lines_created += 1
|
825
|
+
n1 = None
|
826
|
+
dist_n1 = 0.0
|
827
|
+
if not n1:
|
828
|
+
e_prev = self.geom.get_edge_element(n_prev, n)
|
829
|
+
n_prev = n
|
830
|
+
dist_prev = dist
|
831
|
+
alpha_prev = alpha
|
832
|
+
|
833
|
+
return lines_created > 0
|
834
|
+
|
835
|
+
def get_outer_airgap_line(self):
|
836
|
+
logger.debug("begin of get_outer_airgap_line")
|
837
|
+
assert(self.geom.is_outer)
|
838
|
+
assert(self.geom.area_list)
|
839
|
+
|
840
|
+
area = [a for a in self.geom.area_list if a.close_to_ag_startcorner]
|
841
|
+
if len(area) != 1:
|
842
|
+
logger.debug("end of get_outer_airgap_line: %s areas found", len(area))
|
843
|
+
return [], []
|
844
|
+
|
845
|
+
start_node = self.geom.start_corners[0]
|
846
|
+
logger.debug("START NODE %s", start_node)
|
847
|
+
end_node = self.geom.end_corners[0]
|
848
|
+
logger.debug("END NODE %s", end_node)
|
849
|
+
|
850
|
+
return self.get_airgap_line(start_node, end_node, area[0])
|
803
851
|
|
804
852
|
def create_one_area_group(self, areas):
|
805
853
|
logger.debug("begin of create_one_area_group")
|
femagtools/dxfsl/conv.py
CHANGED
@@ -115,6 +115,10 @@ def main():
|
|
115
115
|
help='create fsl',
|
116
116
|
dest='write_fsl',
|
117
117
|
action="store_true")
|
118
|
+
argparser.add_argument('--fsl_single',
|
119
|
+
help='create separate fsl for rotor and stator',
|
120
|
+
dest='write_fsl_single',
|
121
|
+
action="store_true")
|
118
122
|
argparser.add_argument('-v', '--view',
|
119
123
|
help='show a view only',
|
120
124
|
dest='view',
|
@@ -242,6 +246,7 @@ def main():
|
|
242
246
|
show_areas=args.show_areas,
|
243
247
|
small_plots=args.small_plots,
|
244
248
|
write_fsl=args.write_fsl,
|
249
|
+
write_fsl_single=args.write_fsl_single,
|
245
250
|
write_png=args.write_png,
|
246
251
|
write_id=args.write_id,
|
247
252
|
debug_mode=args.debugger,
|
femagtools/dxfsl/converter.py
CHANGED
@@ -12,6 +12,7 @@ from femagtools.dxfsl.plotrenderer import PlotRenderer
|
|
12
12
|
from femagtools.dxfsl.concat import Concatenation
|
13
13
|
from femagtools.dxfsl.functions import Timer, middle_angle
|
14
14
|
from femagtools.dxfsl.journal import Journal, getJournal
|
15
|
+
from femagtools.dxfsl.area import TYPE_WINDINGS
|
15
16
|
import logging
|
16
17
|
import logging.config
|
17
18
|
import numpy as np
|
@@ -180,15 +181,25 @@ def build_machine_rotor(machine, inner, mindist, plt, EESM=False, single=False):
|
|
180
181
|
else:
|
181
182
|
machine_temp = machine
|
182
183
|
|
183
|
-
midangle = middle_angle(machine_temp.startangle,
|
184
|
-
machine_temp.endangle)
|
185
|
-
|
186
184
|
plot_geom(False, # for developer
|
187
185
|
plt, machine_temp.geom,
|
188
|
-
title="Inner Rotor check magnets
|
186
|
+
title="Inner Rotor check magnets")
|
187
|
+
|
188
|
+
machine_slice = machine_temp.get_forced_magnet_slice()
|
189
|
+
if machine_slice:
|
190
|
+
plot_geom(False, # for developer
|
191
|
+
plt, machine_slice.geom,
|
192
|
+
title="Rotor Magnet Slice")
|
193
|
+
|
194
|
+
machine_temp = machine_slice
|
195
|
+
machine_temp.geom.set_rotor()
|
196
|
+
machine_temp.rebuild_subregions(EESM, single=single)
|
197
|
+
plot_geom(False, # for developer
|
198
|
+
plt, machine_temp.geom,
|
199
|
+
title="Rotor Magnet Slice after Rebuild")
|
189
200
|
|
190
201
|
rebuild = False
|
191
|
-
if machine_temp.
|
202
|
+
if machine_temp.has_magnets_in_the_middle():
|
192
203
|
logger.debug("Magnets cut")
|
193
204
|
rebuild = machine_temp.create_mirror_lines_outside_magnets()
|
194
205
|
else:
|
@@ -199,7 +210,7 @@ def build_machine_rotor(machine, inner, mindist, plt, EESM=False, single=False):
|
|
199
210
|
else:
|
200
211
|
rebuild = machine_temp.create_mirror_lines_outside_magnets()
|
201
212
|
if rebuild:
|
202
|
-
machine_temp.geom.
|
213
|
+
machine_temp.geom.create_list_of_areas(delete=True)
|
203
214
|
|
204
215
|
if machine_temp.create_auxiliary_lines():
|
205
216
|
logger.debug("Auxiliary Lines created: rebuild subregions")
|
@@ -239,8 +250,7 @@ def build_machine_stator(machine, inner, mindist, plt, EESM=False, single=False)
|
|
239
250
|
if machine.is_mirrored():
|
240
251
|
plot_geom(False, # for developer
|
241
252
|
plt, machine.previous_machine.geom,
|
242
|
-
title="Mirrored Stator"
|
243
|
-
areas=True)
|
253
|
+
title="Mirrored Stator")
|
244
254
|
|
245
255
|
logger.debug("undo mirrored windings")
|
246
256
|
machine_temp = machine.undo_mirror()
|
@@ -261,6 +271,22 @@ def build_machine_stator(machine, inner, mindist, plt, EESM=False, single=False)
|
|
261
271
|
plt, machine_temp.geom,
|
262
272
|
title="Nodes reduced")
|
263
273
|
|
274
|
+
machine_slice = machine_temp.get_forced_winding_slice()
|
275
|
+
if machine_slice:
|
276
|
+
plot_geom(False, # for developer
|
277
|
+
plt, machine_slice.geom,
|
278
|
+
title="Stator Winding Slice")
|
279
|
+
|
280
|
+
machine_temp = machine_slice
|
281
|
+
machine_temp.geom.set_stator()
|
282
|
+
machine_temp.rebuild_subregions(EESM, single=single)
|
283
|
+
if machine_temp.has_windings_in_the_middle():
|
284
|
+
machine_temp.create_mirror_lines_outside_windings()
|
285
|
+
|
286
|
+
plot_geom(False, # for developer
|
287
|
+
plt, machine_temp.geom,
|
288
|
+
title="Stator Winding Slice after Rebuild")
|
289
|
+
|
264
290
|
if machine_temp.create_auxiliary_lines():
|
265
291
|
machine_temp.rebuild_subregions(EESM, single=single)
|
266
292
|
plot_geom(False, # for developer
|
@@ -273,7 +299,7 @@ def build_machine_stator(machine, inner, mindist, plt, EESM=False, single=False)
|
|
273
299
|
if not machine_temp.is_mirrored():
|
274
300
|
plot_geom(False, # for developer
|
275
301
|
plt, machine_temp.geom,
|
276
|
-
title="Stator before
|
302
|
+
title="Stator before Boundary Corr")
|
277
303
|
machine_temp.create_boundary_nodes()
|
278
304
|
|
279
305
|
plot_geom(False, # for developer
|
@@ -309,6 +335,7 @@ def convert(dxfile,
|
|
309
335
|
show_areas=False,
|
310
336
|
small_plots=False,
|
311
337
|
write_fsl=True,
|
338
|
+
write_fsl_single=False,
|
312
339
|
write_png=False,
|
313
340
|
write_id=False,
|
314
341
|
full_model=False,
|
@@ -362,6 +389,9 @@ def convert(dxfile,
|
|
362
389
|
split_ini = False
|
363
390
|
split_cpy = split
|
364
391
|
|
392
|
+
if write_fsl_single:
|
393
|
+
write_fsl = True
|
394
|
+
|
365
395
|
try:
|
366
396
|
if input_file.suffix in ['.fem', '.FEM']:
|
367
397
|
from .femparser import femshapes
|
@@ -693,6 +723,14 @@ def convert(dxfile,
|
|
693
723
|
fslrenderer = FslRenderer(basename, mtype)
|
694
724
|
inner = fslrenderer.render(machine_inner, inner=True)
|
695
725
|
outer = fslrenderer.render(machine_outer, outer=True)
|
726
|
+
if write_fsl_single:
|
727
|
+
inner_single = fslrenderer.render(machine_inner, inner=True,
|
728
|
+
standalone=True)
|
729
|
+
outer_single = fslrenderer.render(machine_outer, outer=True,
|
730
|
+
standalone=True)
|
731
|
+
else:
|
732
|
+
inner_single = None
|
733
|
+
outer_single = None
|
696
734
|
if full_model:
|
697
735
|
params['num_sl_gen'] = params.get('tot_num_slot', 0)
|
698
736
|
params['agndst'] = agndst(params.get('da1'),
|
@@ -703,10 +741,18 @@ def convert(dxfile,
|
|
703
741
|
|
704
742
|
if params['external_rotor']:
|
705
743
|
conv['fsl_rotor'] = outer
|
744
|
+
if outer_single:
|
745
|
+
conv['fsl_rotor_single'] = outer_single
|
706
746
|
conv['fsl_stator'] = inner
|
747
|
+
if inner_single:
|
748
|
+
conv['fsl_stator_single'] = inner_single
|
707
749
|
else:
|
708
750
|
conv['fsl_rotor'] = inner
|
751
|
+
if inner_single:
|
752
|
+
conv['fsl_rotor_single'] = inner_single
|
709
753
|
conv['fsl_stator'] = outer
|
754
|
+
if outer_single:
|
755
|
+
conv['fsl_stator_single'] = outer_single
|
710
756
|
|
711
757
|
conv['fsl'] = fslrenderer.render_main(
|
712
758
|
machine_inner, machine_outer,
|
@@ -849,11 +895,24 @@ def convert(dxfile,
|
|
849
895
|
if write_fsl:
|
850
896
|
logger.debug("Write fsl")
|
851
897
|
if conv and conv['fsl']:
|
852
|
-
with io.open(basename + '.fsl', 'w',
|
898
|
+
with io.open(basename + '.fsl', 'w',
|
899
|
+
encoding='utf-8') as f:
|
853
900
|
f.write('\n'.join(conv['fsl']))
|
854
901
|
else:
|
855
902
|
logger.warning("No fsl data available")
|
856
903
|
|
904
|
+
if conv:
|
905
|
+
if conv.get('fsl_rotor_single', None):
|
906
|
+
with io.open(basename + '_ROTOR.fsl', 'w',
|
907
|
+
encoding='utf-8') as f:
|
908
|
+
f.write('\n'.join(conv['fsl_rotor_single']))
|
909
|
+
del conv['fsl_rotor_single']
|
910
|
+
if conv.get('fsl_stator_single', None):
|
911
|
+
with io.open(basename + '_STATOR.fsl', 'w',
|
912
|
+
encoding='utf-8') as f:
|
913
|
+
f.write('\n'.join(conv['fsl_stator_single']))
|
914
|
+
del conv['fsl_stator_single']
|
915
|
+
|
857
916
|
conv['name'] = basename
|
858
917
|
t = timer.stop("-- all done in %0.4f seconds --", info=True)
|
859
918
|
journal.put('time_total', t)
|
@@ -874,30 +933,29 @@ def create_femag_parameters(m_inner, m_outer, nodedist=1):
|
|
874
933
|
parts_inner = int(m_inner.get_symmetry_part())
|
875
934
|
parts_outer = int(m_outer.get_symmetry_part())
|
876
935
|
|
877
|
-
|
878
|
-
|
879
|
-
|
880
|
-
|
881
|
-
|
882
|
-
num_poles = int(parts_outer)
|
883
|
-
num_sl_gen = int(geom_inner.get_symmetry_copies()+1)
|
884
|
-
alfa_slot = geom_inner.get_alfa()
|
885
|
-
alfa_pole = geom_outer.get_alfa()
|
936
|
+
if m_inner.geom.is_rotor():
|
937
|
+
geom_slots = geom_outer
|
938
|
+
geom_poles = geom_inner
|
939
|
+
num_slots = int(m_outer.get_symmetry_part())
|
940
|
+
num_poles = int(m_inner.get_symmetry_part())
|
886
941
|
else:
|
887
|
-
|
888
|
-
|
889
|
-
num_slots = int(
|
890
|
-
num_poles = int(
|
891
|
-
|
892
|
-
|
893
|
-
|
942
|
+
geom_slots = geom_inner
|
943
|
+
geom_poles = geom_outer
|
944
|
+
num_slots = int(m_inner.get_symmetry_part())
|
945
|
+
num_poles = int(m_outer.get_symmetry_part())
|
946
|
+
|
947
|
+
slot_area = 0
|
948
|
+
slot_area = geom_slots.area_size_of_type(TYPE_WINDINGS)
|
949
|
+
num_sl_gen = int(geom_slots.get_symmetry_copies()+1)
|
950
|
+
alfa_slot = geom_slots.get_alfa()
|
951
|
+
alfa_pole = geom_poles.get_alfa()
|
894
952
|
|
895
953
|
params['tot_num_slot'] = num_slots
|
896
954
|
params['slot_area'] = slot_area
|
897
955
|
params['num_sl_gen'] = num_sl_gen
|
898
956
|
params['num_poles'] = num_poles
|
899
957
|
params['nodedist'] = nodedist
|
900
|
-
params['external_rotor'] =
|
958
|
+
params['external_rotor'] = m_outer.geom.is_rotor()
|
901
959
|
params['dy1'] = 2*geom_outer.max_radius
|
902
960
|
params['da1'] = 2*geom_outer.min_radius
|
903
961
|
params['da2'] = 2*geom_inner.max_radius
|
femagtools/dxfsl/fslrenderer.py
CHANGED
@@ -236,18 +236,19 @@ class FslRenderer(object):
|
|
236
236
|
geom.start_max_corner(1)),
|
237
237
|
'hair = 1.0',
|
238
238
|
'parts = {}'.format(machine.get_num_parts()),
|
239
|
-
'
|
239
|
+
'rmax = {}'.format(geom.max_radius),
|
240
|
+
'r1 = rmax + hair',
|
240
241
|
'r, phi = c2pr(x0, y0)',
|
241
242
|
'x1, y1 = pr2c(r1, phi)',
|
242
243
|
'x2, y2 = pr2c(r1, {}*math.pi/parts)'.format(slice),
|
243
244
|
f'-- end max corner {geom.end_corners[-1]}',
|
244
245
|
f'-- center {geom.center}',
|
245
|
-
|
246
|
-
'x3, y3 = pr2c(
|
246
|
+
'r2 = {}'.format(geom.dist_end_max_corner(mirrored=False)),
|
247
|
+
'x3, y3 = pr2c(r2, {}*math.pi/parts)'.format(slice),
|
247
248
|
'nc_line(x0, y0, x1, y1, 0)',
|
248
249
|
'nc_circle_m(x1, y1, x2, y2, 0.0, 0.0, 0)',
|
249
250
|
'nc_line(x2, y2, x3, y3, 0)',
|
250
|
-
'x0, y0 = pr2c(
|
251
|
+
'x0, y0 = pr2c(rmax + hair/2, math.pi/parts/2)',
|
251
252
|
'create_mesh_se(x0, y0)',
|
252
253
|
'\n',
|
253
254
|
'outer_da_start = {}'.format(
|