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/__init__.py
CHANGED
femagtools/dxfsl/area.py
CHANGED
@@ -100,6 +100,9 @@ class Area(object):
|
|
100
100
|
def elements(self):
|
101
101
|
return self.area
|
102
102
|
|
103
|
+
def copy_of_elements(self):
|
104
|
+
return [e.clone() for e in self.elements() if e]
|
105
|
+
|
103
106
|
def list_of_nodes(self):
|
104
107
|
if len(self.area) < 1:
|
105
108
|
return
|
@@ -822,9 +825,9 @@ class Area(object):
|
|
822
825
|
mm[3] = max(mm[3], n[3])
|
823
826
|
return mm
|
824
827
|
|
825
|
-
def
|
828
|
+
def intersect_area(self, line):
|
826
829
|
for e in self.area:
|
827
|
-
if e.
|
830
|
+
if e.intersect_shape(line, include_end=True):
|
828
831
|
return True
|
829
832
|
return False
|
830
833
|
|
@@ -1208,6 +1211,7 @@ class Area(object):
|
|
1208
1211
|
|
1209
1212
|
angles.sort(reverse=True)
|
1210
1213
|
# calculate orientation (no rectangle check)
|
1214
|
+
|
1211
1215
|
l, alpha = angles[0]
|
1212
1216
|
phi = normalise_angle(alpha + np.pi/2)
|
1213
1217
|
logger.debug("alpha = %s, phi = %s", alpha, phi)
|
@@ -1216,9 +1220,13 @@ class Area(object):
|
|
1216
1220
|
angle = alpha_angle(mid, phi)
|
1217
1221
|
logger.debug("phi=%s, mid=%s, angle=%s", phi, mid, angle)
|
1218
1222
|
|
1219
|
-
if
|
1223
|
+
if np.isclose(mid, alpha, rtol=1e-3, atol=1e-3):
|
1224
|
+
phi = mid
|
1225
|
+
logger.debug("correction of phi=%s", phi)
|
1226
|
+
elif greater(angle, np.pi * 0.5, rtol=1e-5) and \
|
1220
1227
|
less(angle, np.pi * 1.5, rtol=1e-5):
|
1221
1228
|
phi = normalise_angle(phi + np.pi)
|
1229
|
+
logger.debug("correction of phi=%s", phi)
|
1222
1230
|
|
1223
1231
|
logger.debug("phi of magnet %s is %s", self.identifier(), phi)
|
1224
1232
|
return phi
|
@@ -1321,6 +1329,32 @@ class Area(object):
|
|
1321
1329
|
return np.isclose(angle, border_angle,
|
1322
1330
|
rtol=1e-03, atol=1e-03)
|
1323
1331
|
|
1332
|
+
def set_subregion_parameters(self,
|
1333
|
+
is_inner,
|
1334
|
+
min_radius,
|
1335
|
+
max_radius,
|
1336
|
+
startangle,
|
1337
|
+
endangle):
|
1338
|
+
ag_delta = (max_radius - min_radius) / 500.0
|
1339
|
+
if is_inner:
|
1340
|
+
self.close_to_ag = greater_equal(self.max_dist + ag_delta, max_radius)
|
1341
|
+
close_to_opposition = np.isclose(min_radius, self.min_dist)
|
1342
|
+
airgap_radius = max_radius
|
1343
|
+
opposite_radius = min_radius
|
1344
|
+
else:
|
1345
|
+
self.close_to_ag = less_equal(self.min_dist - ag_delta, min_radius)
|
1346
|
+
close_to_opposition = np.isclose(max_radius, self.max_dist)
|
1347
|
+
airgap_radius = min_radius
|
1348
|
+
opposite_radius = max_radius
|
1349
|
+
|
1350
|
+
airgap_toleranz = (self.max_dist - self.min_dist) / 50.0 # 2%
|
1351
|
+
|
1352
|
+
self.close_to_startangle = np.isclose(self.min_angle, startangle,
|
1353
|
+
1e-04, 1e-04)
|
1354
|
+
self.close_to_endangle = np.isclose(self.max_angle, endangle,
|
1355
|
+
1e-04, 1e-04)
|
1356
|
+
self.surface = self.area_size()
|
1357
|
+
|
1324
1358
|
def mark_stator_subregions(self,
|
1325
1359
|
is_inner,
|
1326
1360
|
stator_size,
|
@@ -1791,6 +1825,16 @@ class Area(object):
|
|
1791
1825
|
for i in a.nested_areas_inside():
|
1792
1826
|
yield i
|
1793
1827
|
|
1828
|
+
def mirror_area(self, center, axis_m, axis_n):
|
1829
|
+
elements = []
|
1830
|
+
for e in self.area:
|
1831
|
+
el = e.mirror_shape(center, axis_m, axis_n)
|
1832
|
+
if el:
|
1833
|
+
elements.append(el)
|
1834
|
+
area = Area(elements, center, 0.0)
|
1835
|
+
area.type = self.type
|
1836
|
+
return area
|
1837
|
+
|
1794
1838
|
def __str__(self):
|
1795
1839
|
return "Area {}\n".format(self.id) + \
|
1796
1840
|
"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
@@ -250,11 +250,6 @@ def main():
|
|
250
250
|
keys = ('tot_num_slot', 'num_sl_gen', 'num_poles', 'nodedist',
|
251
251
|
'dy1', 'da1', 'da2', 'dy2', 'agndst', 'name')
|
252
252
|
logger.info("%s", {k: res[k] for k in keys if k in res})
|
253
|
-
if args.write_fsl:
|
254
|
-
if res is not None:
|
255
|
-
basename = os.path.basename(args.dxfile).split('.')[0]
|
256
|
-
with io.open(basename + '.fsl', 'w', encoding='utf-8') as f:
|
257
|
-
f.write('\n'.join(res['fsl']))
|
258
253
|
|
259
254
|
if __name__ == "__main__":
|
260
255
|
loglevel = logging.INFO
|
femagtools/dxfsl/converter.py
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
"""
|
4
4
|
import os
|
5
|
+
import io
|
5
6
|
from pathlib import Path
|
6
7
|
from femagtools import __version__
|
7
8
|
from femagtools.dxfsl.geom import Geometry
|
@@ -11,6 +12,7 @@ from femagtools.dxfsl.plotrenderer import PlotRenderer
|
|
11
12
|
from femagtools.dxfsl.concat import Concatenation
|
12
13
|
from femagtools.dxfsl.functions import Timer, middle_angle
|
13
14
|
from femagtools.dxfsl.journal import Journal, getJournal
|
15
|
+
from femagtools.dxfsl.area import TYPE_WINDINGS
|
14
16
|
import logging
|
15
17
|
import logging.config
|
16
18
|
import numpy as np
|
@@ -160,12 +162,16 @@ def symmetry_search(machine,
|
|
160
162
|
|
161
163
|
|
162
164
|
def build_machine_rotor(machine, inner, mindist, plt, EESM=False, single=False):
|
165
|
+
global journal
|
163
166
|
logger.debug("Begin of build_machine_rotor")
|
167
|
+
|
164
168
|
if machine.has_windings():
|
165
169
|
logger.debug("do nothing here with windings in rotor")
|
166
170
|
logger.debug("End of build_machine_rotor")
|
167
171
|
return machine
|
168
172
|
|
173
|
+
timer = Timer(start_it=True)
|
174
|
+
|
169
175
|
if machine.is_mirrored():
|
170
176
|
logger.debug("Rotor is mirrored")
|
171
177
|
machine_temp = machine.undo_mirror()
|
@@ -175,15 +181,25 @@ def build_machine_rotor(machine, inner, mindist, plt, EESM=False, single=False):
|
|
175
181
|
else:
|
176
182
|
machine_temp = machine
|
177
183
|
|
178
|
-
midangle = middle_angle(machine_temp.startangle,
|
179
|
-
machine_temp.endangle)
|
180
|
-
|
181
184
|
plot_geom(False, # for developer
|
182
185
|
plt, machine_temp.geom,
|
183
|
-
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")
|
184
200
|
|
185
201
|
rebuild = False
|
186
|
-
if machine_temp.
|
202
|
+
if machine_temp.has_magnets_in_the_middle():
|
187
203
|
logger.debug("Magnets cut")
|
188
204
|
rebuild = machine_temp.create_mirror_lines_outside_magnets()
|
189
205
|
else:
|
@@ -194,7 +210,7 @@ def build_machine_rotor(machine, inner, mindist, plt, EESM=False, single=False):
|
|
194
210
|
else:
|
195
211
|
rebuild = machine_temp.create_mirror_lines_outside_magnets()
|
196
212
|
if rebuild:
|
197
|
-
machine_temp.geom.
|
213
|
+
machine_temp.geom.create_list_of_areas(delete=True)
|
198
214
|
|
199
215
|
if machine_temp.create_auxiliary_lines():
|
200
216
|
logger.debug("Auxiliary Lines created: rebuild subregions")
|
@@ -207,25 +223,34 @@ def build_machine_rotor(machine, inner, mindist, plt, EESM=False, single=False):
|
|
207
223
|
machine_temp.create_inner_corner_areas()
|
208
224
|
|
209
225
|
if not machine_temp.is_mirrored():
|
210
|
-
|
226
|
+
plot_geom(False, # for developer
|
227
|
+
plt, machine_temp.geom,
|
228
|
+
title="Rotor before Boundery Corr")
|
229
|
+
machine_temp.create_boundary_nodes()
|
211
230
|
|
212
231
|
plot_geom(False, # for developer
|
213
232
|
plt, machine_temp.geom,
|
214
233
|
title="Final Rotor")
|
234
|
+
|
235
|
+
t = timer.stop("-- rotor created in %0.4f seconds --")
|
236
|
+
journal.put('time_rotor_created', t)
|
237
|
+
|
215
238
|
logger.debug("End of build_machine_rotor")
|
216
239
|
return machine_temp
|
217
240
|
|
218
241
|
|
219
242
|
def build_machine_stator(machine, inner, mindist, plt, EESM=False, single=False):
|
243
|
+
global journal
|
220
244
|
logger.debug("Begin of build_machine_stator")
|
245
|
+
timer = Timer(start_it=True)
|
246
|
+
|
221
247
|
if not machine.geom.is_stator():
|
222
248
|
logger.debug("Rotor with windings")
|
223
249
|
|
224
250
|
if machine.is_mirrored():
|
225
251
|
plot_geom(False, # for developer
|
226
252
|
plt, machine.previous_machine.geom,
|
227
|
-
title="Mirrored Stator"
|
228
|
-
areas=True)
|
253
|
+
title="Mirrored Stator")
|
229
254
|
|
230
255
|
logger.debug("undo mirrored windings")
|
231
256
|
machine_temp = machine.undo_mirror()
|
@@ -240,25 +265,50 @@ def build_machine_stator(machine, inner, mindist, plt, EESM=False, single=False)
|
|
240
265
|
else:
|
241
266
|
machine_temp = machine
|
242
267
|
|
243
|
-
rebuild = machine_temp.create_auxiliary_lines()
|
244
268
|
if machine_temp.geom.reduce_element_nodes(mindist):
|
269
|
+
machine_temp.rebuild_subregions(EESM, single=single)
|
245
270
|
plot_geom(False, # for developer
|
246
271
|
plt, machine_temp.geom,
|
247
|
-
title="Nodes reduced"
|
248
|
-
|
249
|
-
|
250
|
-
if
|
272
|
+
title="Nodes reduced")
|
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()
|
251
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
|
+
|
290
|
+
if machine_temp.create_auxiliary_lines():
|
291
|
+
machine_temp.rebuild_subregions(EESM, single=single)
|
292
|
+
plot_geom(False, # for developer
|
293
|
+
plt, machine_temp.geom,
|
294
|
+
title="Stator with Auxiliary Lines")
|
252
295
|
|
253
296
|
if inner:
|
254
297
|
machine_temp.create_inner_corner_areas()
|
255
298
|
|
256
299
|
if not machine_temp.is_mirrored():
|
257
|
-
|
300
|
+
plot_geom(False, # for developer
|
301
|
+
plt, machine_temp.geom,
|
302
|
+
title="Stator before Boundary Corr")
|
303
|
+
machine_temp.create_boundary_nodes()
|
258
304
|
|
259
305
|
plot_geom(False, # for developer
|
260
306
|
plt, machine_temp.geom,
|
261
307
|
title="Final Stator")
|
308
|
+
|
309
|
+
t = timer.stop("-- stator created in %0.4f seconds --")
|
310
|
+
journal.put('time_stator_created', t)
|
311
|
+
|
262
312
|
logger.debug("End of build_machine_stator")
|
263
313
|
return machine_temp
|
264
314
|
|
@@ -290,6 +340,7 @@ def convert(dxfile,
|
|
290
340
|
full_model=False,
|
291
341
|
debug_mode=False,
|
292
342
|
write_journal=False):
|
343
|
+
global journal
|
293
344
|
layers = ()
|
294
345
|
conv = {}
|
295
346
|
|
@@ -816,10 +867,19 @@ def convert(dxfile,
|
|
816
867
|
|
817
868
|
mtype = 'EESM' if EESM else 'PMSM'
|
818
869
|
fslrenderer = FslRenderer(basename, mtype)
|
819
|
-
conv['fsl'] = fslrenderer.render(machine, inner, outer)
|
870
|
+
conv['fsl'] = fslrenderer.render(machine, inner, outer, standalone=True)
|
820
871
|
|
821
872
|
if params is not None:
|
822
873
|
conv.update(params)
|
874
|
+
|
875
|
+
if write_fsl:
|
876
|
+
logger.debug("Write fsl")
|
877
|
+
if conv and conv['fsl']:
|
878
|
+
with io.open(basename + '.fsl', 'w', encoding='utf-8') as f:
|
879
|
+
f.write('\n'.join(conv['fsl']))
|
880
|
+
else:
|
881
|
+
logger.warning("No fsl data available")
|
882
|
+
|
823
883
|
conv['name'] = basename
|
824
884
|
t = timer.stop("-- all done in %0.4f seconds --", info=True)
|
825
885
|
journal.put('time_total', t)
|
@@ -840,30 +900,29 @@ def create_femag_parameters(m_inner, m_outer, nodedist=1):
|
|
840
900
|
parts_inner = int(m_inner.get_symmetry_part())
|
841
901
|
parts_outer = int(m_outer.get_symmetry_part())
|
842
902
|
|
843
|
-
|
844
|
-
|
845
|
-
|
846
|
-
|
847
|
-
|
848
|
-
num_poles = int(parts_outer)
|
849
|
-
num_sl_gen = int(geom_inner.get_symmetry_copies()+1)
|
850
|
-
alfa_slot = geom_inner.get_alfa()
|
851
|
-
alfa_pole = geom_outer.get_alfa()
|
903
|
+
if m_inner.geom.is_rotor():
|
904
|
+
geom_slots = geom_outer
|
905
|
+
geom_poles = geom_inner
|
906
|
+
num_slots = int(m_outer.get_symmetry_part())
|
907
|
+
num_poles = int(m_inner.get_symmetry_part())
|
852
908
|
else:
|
853
|
-
|
854
|
-
|
855
|
-
num_slots = int(
|
856
|
-
num_poles = int(
|
857
|
-
|
858
|
-
|
859
|
-
|
909
|
+
geom_slots = geom_inner
|
910
|
+
geom_poles = geom_outer
|
911
|
+
num_slots = int(m_inner.get_symmetry_part())
|
912
|
+
num_poles = int(m_outer.get_symmetry_part())
|
913
|
+
|
914
|
+
slot_area = 0
|
915
|
+
slot_area = geom_slots.area_size_of_type(TYPE_WINDINGS)
|
916
|
+
num_sl_gen = int(geom_slots.get_symmetry_copies()+1)
|
917
|
+
alfa_slot = geom_slots.get_alfa()
|
918
|
+
alfa_pole = geom_poles.get_alfa()
|
860
919
|
|
861
920
|
params['tot_num_slot'] = num_slots
|
862
921
|
params['slot_area'] = slot_area
|
863
922
|
params['num_sl_gen'] = num_sl_gen
|
864
923
|
params['num_poles'] = num_poles
|
865
924
|
params['nodedist'] = nodedist
|
866
|
-
params['external_rotor'] =
|
925
|
+
params['external_rotor'] = m_outer.geom.is_rotor()
|
867
926
|
params['dy1'] = 2*geom_outer.max_radius
|
868
927
|
params['da1'] = 2*geom_outer.min_radius
|
869
928
|
params['da2'] = 2*geom_inner.max_radius
|
femagtools/dxfsl/fslrenderer.py
CHANGED
@@ -154,7 +154,7 @@ class FslRenderer(object):
|
|
154
154
|
return sorted([(abs(r - np.linalg.norm(e.center_of_connection())), e)
|
155
155
|
for e in geom.elements(Shape)])
|
156
156
|
|
157
|
-
def render(self, machine, inner=False, outer=False):
|
157
|
+
def render(self, machine, inner=False, outer=False, standalone=False):
|
158
158
|
'''create fsl statements with nodechains'''
|
159
159
|
machine.set_alfa_and_corners()
|
160
160
|
geom = machine.geom
|
@@ -162,6 +162,14 @@ class FslRenderer(object):
|
|
162
162
|
geom.split_all_lines_longer_than(split_len)
|
163
163
|
self.content = []
|
164
164
|
|
165
|
+
if standalone:
|
166
|
+
self.content += ['if (agndst == nil) then',
|
167
|
+
' agndst = 0.5',
|
168
|
+
' m.npols_gen = 2',
|
169
|
+
' m.num_sl_gen = 2',
|
170
|
+
' new_model_force("{}","Test")'.format(self.model),
|
171
|
+
'end']
|
172
|
+
|
165
173
|
MAXDST=4.0
|
166
174
|
NUMLEVELS=10
|
167
175
|
NDT0=1.1
|
@@ -228,18 +236,19 @@ class FslRenderer(object):
|
|
228
236
|
geom.start_max_corner(1)),
|
229
237
|
'hair = 1.0',
|
230
238
|
'parts = {}'.format(machine.get_num_parts()),
|
231
|
-
'
|
239
|
+
'rmax = {}'.format(geom.max_radius),
|
240
|
+
'r1 = rmax + hair',
|
232
241
|
'r, phi = c2pr(x0, y0)',
|
233
242
|
'x1, y1 = pr2c(r1, phi)',
|
234
243
|
'x2, y2 = pr2c(r1, {}*math.pi/parts)'.format(slice),
|
235
244
|
f'-- end max corner {geom.end_corners[-1]}',
|
236
245
|
f'-- center {geom.center}',
|
237
|
-
|
238
|
-
'x3, y3 = pr2c(
|
246
|
+
'r2 = {}'.format(geom.dist_end_max_corner(mirrored=False)),
|
247
|
+
'x3, y3 = pr2c(r2, {}*math.pi/parts)'.format(slice),
|
239
248
|
'nc_line(x0, y0, x1, y1, 0)',
|
240
249
|
'nc_circle_m(x1, y1, x2, y2, 0.0, 0.0, 0)',
|
241
250
|
'nc_line(x2, y2, x3, y3, 0)',
|
242
|
-
'x0, y0 = pr2c(
|
251
|
+
'x0, y0 = pr2c(rmax + hair/2, math.pi/parts/2)',
|
243
252
|
'create_mesh_se(x0, y0)',
|
244
253
|
'\n',
|
245
254
|
'outer_da_start = {}'.format(
|