femagtools 1.8.18__py3-none-any.whl → 1.8.19__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/bch.py +23 -6
- femagtools/dxfsl/area.py +1 -1
- femagtools/dxfsl/areabuilder.py +28 -12
- femagtools/dxfsl/converter.py +2 -0
- femagtools/dxfsl/fslrenderer.py +3 -0
- femagtools/dxfsl/geom.py +64 -39
- femagtools/dxfsl/machine.py +101 -2
- femagtools/isa7.py +25 -22
- femagtools/machine/__init__.py +2 -2
- femagtools/machine/effloss.py +8 -0
- femagtools/machine/pm.py +16 -6
- femagtools/machine/sm.py +17 -6
- femagtools/mcv.py +4 -1
- femagtools/shortcircuit.py +8 -7
- femagtools/templates/psi-torq-rem.mako +4 -4
- femagtools/templates/statorKS1.mako +43 -0
- {femagtools-1.8.18.dist-info → femagtools-1.8.19.dist-info}/METADATA +1 -1
- {femagtools-1.8.18.dist-info → femagtools-1.8.19.dist-info}/RECORD +23 -22
- {femagtools-1.8.18.dist-info → femagtools-1.8.19.dist-info}/WHEEL +0 -0
- {femagtools-1.8.18.dist-info → femagtools-1.8.19.dist-info}/entry_points.txt +0 -0
- {femagtools-1.8.18.dist-info → femagtools-1.8.19.dist-info}/licenses/LICENSE +0 -0
- {femagtools-1.8.18.dist-info → femagtools-1.8.19.dist-info}/top_level.txt +0 -0
femagtools/__init__.py
CHANGED
femagtools/bch.py
CHANGED
@@ -271,7 +271,7 @@ class Reader:
|
|
271
271
|
return self.flux[0]['displ'][1]-self.flux[0]['displ'][0]
|
272
272
|
return None
|
273
273
|
|
274
|
-
def read(self, content):
|
274
|
+
def read(self, content, **kwargs):
|
275
275
|
"""read bch file
|
276
276
|
|
277
277
|
Args:
|
@@ -297,7 +297,10 @@ class Reader:
|
|
297
297
|
if k == title2[:len(k)]:
|
298
298
|
title = title2[:len(k)]
|
299
299
|
if title in self.dispatch:
|
300
|
-
|
300
|
+
if title == 'Airgap Induction Br':
|
301
|
+
self.dispatch[title](self, s, kwargs.get('ignore_airgap_induction_with_c_step_section', True))
|
302
|
+
else:
|
303
|
+
self.dispatch[title](self, s)
|
301
304
|
|
302
305
|
if len(self.weights) > 0:
|
303
306
|
w = list(zip(*self.weights))
|
@@ -887,7 +890,7 @@ class Reader:
|
|
887
890
|
self.flux_fft[self.wdg] = []
|
888
891
|
self.flux_fft[self.wdg].append(flux_fft)
|
889
892
|
|
890
|
-
def __read_airgapInduction(self, content):
|
893
|
+
def __read_airgapInduction(self, content, ignore_c_step_section=True):
|
891
894
|
"read and append airgapInduction section"
|
892
895
|
import scipy.integrate as si
|
893
896
|
import math
|
@@ -918,7 +921,9 @@ class Reader:
|
|
918
921
|
i1beta = True
|
919
922
|
continue
|
920
923
|
if line.startswith("C_STEP"):
|
921
|
-
|
924
|
+
if ignore_c_step_section:
|
925
|
+
return # ignore this section
|
926
|
+
continue
|
922
927
|
try:
|
923
928
|
rec = self.__findNums(line)
|
924
929
|
if len(rec) == 10:
|
@@ -966,6 +971,10 @@ class Reader:
|
|
966
971
|
self.airgapInduction['iq'] = iq
|
967
972
|
self.airgapInduction['id'] = id
|
968
973
|
nrows = len(self.airgapInduction['id'])
|
974
|
+
if not ignore_c_step_section:
|
975
|
+
# min 1 required (section with C_STEP)
|
976
|
+
nrows = max(1, nrows)
|
977
|
+
ncols = max(1, ncols)
|
969
978
|
|
970
979
|
try:
|
971
980
|
self.airgapInduction['an'] = [np.reshape(an[j][:nrows*ncols],
|
@@ -999,6 +1008,14 @@ class Reader:
|
|
999
1008
|
[1:])
|
1000
1009
|
self.airgapInduction['Bm'] = zip(*zip(*self.airgapInduction['Bm'])
|
1001
1010
|
[1:])
|
1011
|
+
elif not ignore_c_step_section:
|
1012
|
+
# section with C_STEP and a single data linex
|
1013
|
+
self.airgapInduction['an'] = [self.airgapInduction['an'][i][0:]
|
1014
|
+
for i in range(4)]
|
1015
|
+
self.airgapInduction['bn'] = [self.airgapInduction['bn'][i][0:]
|
1016
|
+
for i in range(4)]
|
1017
|
+
self.airgapInduction['Ba'] = self.airgapInduction['Ba'][0:]
|
1018
|
+
self.airgapInduction['Bm'] = self.airgapInduction['Bm'][0:]
|
1002
1019
|
except ValueError:
|
1003
1020
|
print(self.airgapInduction['i1'])
|
1004
1021
|
|
@@ -1858,12 +1875,12 @@ class Reader:
|
|
1858
1875
|
return self.__str__()
|
1859
1876
|
|
1860
1877
|
|
1861
|
-
def read(filename):
|
1878
|
+
def read(filename, **kwargs):
|
1862
1879
|
"""Read BCH/BATCH results from file *filename*."""
|
1863
1880
|
import io
|
1864
1881
|
bchresults = Reader()
|
1865
1882
|
with io.open(filename, encoding='latin1', errors='ignore') as f:
|
1866
|
-
bchresults.read(f.readlines())
|
1883
|
+
bchresults.read(f.readlines(), **kwargs)
|
1867
1884
|
return bchresults
|
1868
1885
|
|
1869
1886
|
|
femagtools/dxfsl/area.py
CHANGED
@@ -1818,7 +1818,7 @@ class Area(object):
|
|
1818
1818
|
logger.debug(">>> air is a circle")
|
1819
1819
|
return self.type
|
1820
1820
|
|
1821
|
-
self.set_close_to_start_end_angles(
|
1821
|
+
self.set_close_to_start_end_angles(0.0, alpha)
|
1822
1822
|
|
1823
1823
|
if self.is_magnet_rectangle():
|
1824
1824
|
self.type = TYPE_MAGNET_RECT # magnet embedded
|
femagtools/dxfsl/areabuilder.py
CHANGED
@@ -16,7 +16,7 @@ from femagtools.dxfsl.area import Area, TYPE_AIR
|
|
16
16
|
from femagtools.dxfsl.functions import points_are_close, nodes_are_equal, distance
|
17
17
|
from femagtools.dxfsl.functions import normalise_angle, positive_angle, point
|
18
18
|
from femagtools.dxfsl.functions import alpha_line, alpha_points, alpha_angle
|
19
|
-
from femagtools.dxfsl.functions import less, is_same_angle
|
19
|
+
from femagtools.dxfsl.functions import less, less_equal, greater, is_same_angle
|
20
20
|
from femagtools.dxfsl.functions import Timer
|
21
21
|
from femagtools.dxfsl.journal import getJournal
|
22
22
|
import io
|
@@ -135,7 +135,7 @@ class EdgeInfo(object):
|
|
135
135
|
self.angle = positive_angle(alpha_angle(start_angle, self.n1_angle_ingoing()))
|
136
136
|
logger.debug("set_direction_angle: angle is %s", self.angle)
|
137
137
|
|
138
|
-
if is_same_angle(0.0, self.angle, atol=0.
|
138
|
+
if is_same_angle(0.0, self.angle, atol=0.015): # 1/2 degree
|
139
139
|
# reverse direction
|
140
140
|
logger.debug("set_direction_angle: reverse direction( nearly 180 degrees)")
|
141
141
|
|
@@ -218,7 +218,7 @@ class EdgeInfo(object):
|
|
218
218
|
myself_angle = self.angle
|
219
219
|
other_angle = nbr_edge.angle
|
220
220
|
|
221
|
-
if is_same_angle(0.0, myself_angle):
|
221
|
+
if is_same_angle(0.0, myself_angle, atol=0.015):
|
222
222
|
# 360 or 0 degrees => turn 180 degrees
|
223
223
|
logger.debug("-- ATTENTION: myself %s turns nearly 180 degrees", self.classname())
|
224
224
|
logger.debug(" the angle is %s", myself_angle)
|
@@ -261,7 +261,7 @@ class EdgeInfo(object):
|
|
261
261
|
logger.debug("#4: end of myself_direction_lefthand: ==> %s", left)
|
262
262
|
return left
|
263
263
|
|
264
|
-
if is_same_angle(0.0, other_angle, atol=0.
|
264
|
+
if is_same_angle(0.0, other_angle, atol=0.015): # 1/2 degree
|
265
265
|
# 360 or 0 degrees => turn 180 degrees
|
266
266
|
logger.debug("-- ATTENTION: other %s turns nearly 180 degrees", nbr_edge.classname())
|
267
267
|
logger.debug(" the angle is %s", other_angle)
|
@@ -288,7 +288,7 @@ class EdgeInfo(object):
|
|
288
288
|
|
289
289
|
logger.debug("-- angles: myself = %s, other = %s",
|
290
290
|
myself_angle, other_angle)
|
291
|
-
if not is_same_angle(myself_angle, other_angle, atol=0.
|
291
|
+
if not is_same_angle(myself_angle, other_angle, atol=0.015): # 1/2 degree
|
292
292
|
logger.debug("-- angles are different")
|
293
293
|
left = myself_angle > other_angle
|
294
294
|
log_lefthand(left, self, nbr_edge)
|
@@ -778,7 +778,7 @@ class AreaBuilder(object):
|
|
778
778
|
assert(self.geom.area_list)
|
779
779
|
return self.get_lower_border_line()
|
780
780
|
|
781
|
-
def close_outer_winding_areas(self):
|
781
|
+
def close_outer_winding_areas(self, color='red'):
|
782
782
|
logger.debug("begin close_outer_winding_areas")
|
783
783
|
|
784
784
|
airgap_line, airgap_el = self.get_outer_airgap_line()
|
@@ -787,6 +787,15 @@ class AreaBuilder(object):
|
|
787
787
|
if len(airgap_line) < 5:
|
788
788
|
return False
|
789
789
|
|
790
|
+
distlist = [distance(self.geom.center, n) for n in airgap_line]
|
791
|
+
min_dist = min(distlist)
|
792
|
+
max_dist = max(distlist)
|
793
|
+
geom_height = self.geom.max_radius - self.geom.min_radius
|
794
|
+
line_height = max_dist - min_dist
|
795
|
+
if line_height < geom_height * 0.2:
|
796
|
+
return 0
|
797
|
+
|
798
|
+
logger.debug("NODES: %s TO %s", airgap_line[0], airgap_line[-1])
|
790
799
|
n1 = None
|
791
800
|
dist_n1 = 0.0
|
792
801
|
|
@@ -795,22 +804,29 @@ class AreaBuilder(object):
|
|
795
804
|
dist_prev = distance(self.geom.center, n_prev)
|
796
805
|
alpha_prev = alpha_line(self.geom.center, n_prev)
|
797
806
|
alpha_start = alpha_prev
|
798
|
-
|
799
807
|
lines_created = 0
|
808
|
+
dist_ag = self.geom.min_radius
|
809
|
+
logger.debug("MIN RADIUS DIST: %s",dist_ag)
|
800
810
|
for n in airgap_line[1:]:
|
801
811
|
dist = distance(self.geom.center, n)
|
802
812
|
alpha = alpha_line(self.geom.center, n)
|
813
|
+
logger.debug("Node %s, dist=%s, alpha=%s", n, dist, alpha)
|
803
814
|
if not n1:
|
804
|
-
|
805
|
-
|
806
|
-
|
815
|
+
logger.debug("Previous, dist=%s, alpha=%s", dist_prev, alpha_prev)
|
816
|
+
if greater(dist_prev, dist_ag, rtol=1e-3, atol=1e-3):
|
817
|
+
if greater(dist, dist_prev, rtol=1e-3, atol=1e-3) and \
|
818
|
+
less(alpha, alpha_prev, rtol=1e-4, atol=1e-5):
|
819
|
+
n1 = n_prev
|
820
|
+
dist_n1 = dist_prev
|
821
|
+
logger.debug("NODE1: %s (%s)", n1, dist_n1)
|
807
822
|
else:
|
808
|
-
if
|
823
|
+
if less_equal(dist, dist_n1, rtol=1e-3, atol=1e-2):
|
824
|
+
logger.debug("NODE2: %s (%s)", n, dist)
|
809
825
|
line = Line(Element(start=n1, end=n))
|
810
826
|
if e_prev.intersect_line(line):
|
811
827
|
logger.debug("___LINE NOT POSSIBLE___")
|
812
828
|
else:
|
813
|
-
self.geom.add_line(n1, n, color=
|
829
|
+
self.geom.add_line(n1, n, color=color)
|
814
830
|
lines_created += 1
|
815
831
|
n1 = None
|
816
832
|
dist_n1 = 0.0
|
femagtools/dxfsl/converter.py
CHANGED
@@ -286,6 +286,8 @@ def build_machine_stator(machine, inner, mindist, plt, EESM=False, single=False)
|
|
286
286
|
machine_temp.create_mirror_lines_outside_windings()
|
287
287
|
else:
|
288
288
|
machine_temp = machine
|
289
|
+
if machine_temp.has_windings_in_the_middle():
|
290
|
+
machine_temp.create_mirror_lines_outside_windings()
|
289
291
|
|
290
292
|
if machine_temp.geom.reduce_element_nodes(mindist):
|
291
293
|
machine_temp.rebuild_subregions(EESM, single=single)
|
femagtools/dxfsl/fslrenderer.py
CHANGED
@@ -256,6 +256,9 @@ class FslRenderer(object):
|
|
256
256
|
'if mcvkey_yoke == nil then',
|
257
257
|
' mcvkey_yoke = "dummy"',
|
258
258
|
' ur = 1000.0',
|
259
|
+
' else if mcvkey_teeth == nil then',
|
260
|
+
' mcvkey_teeth = mcvkey_yoke',
|
261
|
+
'end',
|
259
262
|
'end',
|
260
263
|
'x0_iron_tooth, y0_iron_tooth = 0.0, 0.0',
|
261
264
|
'x0_iron_yoke, y0_iron_yoke = 0.0, 0.0',
|
femagtools/dxfsl/geom.py
CHANGED
@@ -1182,7 +1182,7 @@ class Geometry(object):
|
|
1182
1182
|
nx.set_edge_attributes(self.g, False, 1)
|
1183
1183
|
nx.set_edge_attributes(self.g, False, 2)
|
1184
1184
|
|
1185
|
-
def create_list_of_areas(self, main=False, delete=False):
|
1185
|
+
def create_list_of_areas(self, main=False, delete=False, nolog=True):
|
1186
1186
|
""" return list of areas for each node and their neighbors
|
1187
1187
|
"""
|
1188
1188
|
if delete: # clear list of areas
|
@@ -1193,7 +1193,7 @@ class Geometry(object):
|
|
1193
1193
|
# list already available
|
1194
1194
|
return
|
1195
1195
|
|
1196
|
-
areabuilder = AreaBuilder(geom=self)
|
1196
|
+
areabuilder = AreaBuilder(geom=self, nolog=nolog)
|
1197
1197
|
areabuilder.create_list_of_areas(main=main)
|
1198
1198
|
self.area_list = areabuilder.area_list
|
1199
1199
|
logger.debug("area list created")
|
@@ -3337,6 +3337,31 @@ class Geometry(object):
|
|
3337
3337
|
return [a for a in self.list_of_areas()
|
3338
3338
|
if a.is_type(type)]
|
3339
3339
|
|
3340
|
+
def is_tooth(self, a, windings, wdg_min_dist, wdg_max_dist):
|
3341
|
+
if a.around_windings(windings, self):
|
3342
|
+
if a.close_to_ag:
|
3343
|
+
return True
|
3344
|
+
if self.is_inner:
|
3345
|
+
if greater(a.min_dist, wdg_min_dist, atol=1e-1):
|
3346
|
+
return True
|
3347
|
+
else:
|
3348
|
+
if less(a.max_dist, wdg_max_dist, atol=1e-1):
|
3349
|
+
return True
|
3350
|
+
return False
|
3351
|
+
|
3352
|
+
def between_airgap_and_winding(self, a,
|
3353
|
+
wdg_min_angle,
|
3354
|
+
wdg_max_angle,
|
3355
|
+
wdg_min_dist,
|
3356
|
+
wdg_max_dist):
|
3357
|
+
if greater_equal(a.min_angle, wdg_min_angle) and \
|
3358
|
+
less_equal(a.max_angle, wdg_max_angle):
|
3359
|
+
if self.is_inner:
|
3360
|
+
return less_equal(wdg_max_dist, a.min_dist)
|
3361
|
+
else:
|
3362
|
+
return less_equal(a.max_dist, wdg_min_dist)
|
3363
|
+
return False
|
3364
|
+
|
3340
3365
|
def collect_windings(self):
|
3341
3366
|
logger.debug("begin of collect_windings")
|
3342
3367
|
good_windings = self.get_windings(AREA.TYPE_WINDINGS)
|
@@ -3409,7 +3434,7 @@ class Geometry(object):
|
|
3409
3434
|
max_size, max_w = windings_surface[0]
|
3410
3435
|
for sz, w in windings_surface[1:]:
|
3411
3436
|
logger.debug("winding size = %s", sz)
|
3412
|
-
if sz / max_size < 0.
|
3437
|
+
if sz / max_size < 0.60:
|
3413
3438
|
w.set_type(AREA.TYPE_AIR)
|
3414
3439
|
if sz / max_size < 0.2:
|
3415
3440
|
windings_found -= 1
|
@@ -3459,7 +3484,7 @@ class Geometry(object):
|
|
3459
3484
|
air_areas = [a for a in self.list_of_areas()
|
3460
3485
|
if a.is_type(AREA.TYPE_AIR_OR_IRON)]
|
3461
3486
|
for a in air_areas:
|
3462
|
-
if a.around_windings(windings, self):
|
3487
|
+
if a.around_windings(windings, self) and less(a.min_dist, wdg_max_dist - 0.5):
|
3463
3488
|
logger.debug("Area %s", a.identifier())
|
3464
3489
|
logger.debug(" - air-angle min/max = %s/%s",
|
3465
3490
|
a.min_air_angle,
|
@@ -3481,7 +3506,6 @@ class Geometry(object):
|
|
3481
3506
|
a.close_to_ag):
|
3482
3507
|
a.set_type(AREA.TYPE_AIR) # air
|
3483
3508
|
continue
|
3484
|
-
|
3485
3509
|
a.set_type(AREA.TYPE_TOOTH) # iron shaft (Zahn)
|
3486
3510
|
continue
|
3487
3511
|
|
@@ -3510,14 +3534,28 @@ class Geometry(object):
|
|
3510
3534
|
a.set_type(AREA.TYPE_TOOTH) # iron shaft (Zahn)
|
3511
3535
|
else:
|
3512
3536
|
logger.debug("#5 not around windings")
|
3513
|
-
|
3537
|
+
if self.between_airgap_and_winding(a,
|
3538
|
+
wdg_min_angle, wdg_max_angle,
|
3539
|
+
wdg_min_dist, wdg_max_dist):
|
3540
|
+
a.set_type(AREA.TYPE_AIR) # air
|
3541
|
+
else:
|
3542
|
+
if self.is_inner:
|
3543
|
+
if greater(a.min_dist, wdg_min_dist, atol=1e-1):
|
3544
|
+
a.set_type(AREA.TYPE_TOOTH) # iron shaft (Zahn)
|
3545
|
+
else:
|
3546
|
+
a.set_type(AREA.TYPE_YOKE) # iron shaft (Joch)
|
3547
|
+
else:
|
3548
|
+
if less(a.max_dist, wdg_max_dist, atol=1e-1):
|
3549
|
+
a.set_type(AREA.TYPE_TOOTH) # iron shaft (Zahn)
|
3550
|
+
else:
|
3551
|
+
a.set_type(AREA.TYPE_YOKE) # iron shaft (Joch)
|
3514
3552
|
|
3515
3553
|
# yoke or shaft ?
|
3516
3554
|
iron_areas = [a for a in self.list_of_areas()
|
3517
3555
|
if a.is_type(AREA.TYPE_YOKE)]
|
3518
3556
|
for a in iron_areas:
|
3519
3557
|
if a.around_windings(windings, self):
|
3520
|
-
if less(a.min_dist, wdg_max_dist):
|
3558
|
+
if less(a.min_dist, wdg_max_dist - 0.5):
|
3521
3559
|
if less_equal(a.max_dist, wdg_max_dist):
|
3522
3560
|
a.set_type(AREA.TYPE_TOOTH) # iron shaft (Zahn)
|
3523
3561
|
else:
|
@@ -3922,6 +3960,15 @@ class Geometry(object):
|
|
3922
3960
|
area.mark_airgap_corners(start_cp, end_cp)
|
3923
3961
|
return
|
3924
3962
|
|
3963
|
+
def get_areas_of_type(self, types=()):
|
3964
|
+
return [area for area in self.list_of_areas()
|
3965
|
+
if area.type in types]
|
3966
|
+
|
3967
|
+
def get_areas_of_irons(self):
|
3968
|
+
return self.get_areas_of_type((AREA.TYPE_IRON,
|
3969
|
+
AREA.TYPE_YOKE,
|
3970
|
+
AREA.TYPE_TOOTH,))
|
3971
|
+
|
3925
3972
|
def num_areas_of_type(self, types=()):
|
3926
3973
|
return len([area for area in self.list_of_areas()
|
3927
3974
|
if area.type in types])
|
@@ -4268,6 +4315,16 @@ class Geometry(object):
|
|
4268
4315
|
for e in self.elements():
|
4269
4316
|
e.adjust_points()
|
4270
4317
|
|
4318
|
+
def split_with_point(self, p):
|
4319
|
+
for e in self.elements(Shape):
|
4320
|
+
elements = e.split([p])
|
4321
|
+
if elements:
|
4322
|
+
self.remove_edge(e)
|
4323
|
+
for e in elements:
|
4324
|
+
self.add_element(e, rtol=self.rtol, atol=self.atol)
|
4325
|
+
return True
|
4326
|
+
return False
|
4327
|
+
|
4271
4328
|
def split_and_get_intersect_points(self, el, aktion=True, include_end=True):
|
4272
4329
|
logger.debug("begin of split_and_get_intersect_points")
|
4273
4330
|
rtol = 1e-03
|
@@ -4424,38 +4481,6 @@ class Geometry(object):
|
|
4424
4481
|
builder = AreaBuilder(geom=self)
|
4425
4482
|
return builder.create_inner_corner_auxiliary_areas(startangle, endangle)
|
4426
4483
|
|
4427
|
-
def analyse_airgap_line(self, inner):
|
4428
|
-
if inner: # TODO
|
4429
|
-
return False
|
4430
|
-
|
4431
|
-
areas = self.list_of_areas()
|
4432
|
-
builder = AreaBuilder(geom=self)
|
4433
|
-
ag_nodes, ag_el = builder.get_outer_airgap_line()
|
4434
|
-
if not ag_nodes:
|
4435
|
-
logger.warning("Fatal: No nodes found")
|
4436
|
-
return False
|
4437
|
-
|
4438
|
-
distlist = [distance(self.center, n) for n in ag_nodes]
|
4439
|
-
min_dist = min(distlist)
|
4440
|
-
max_dist = max(distlist)
|
4441
|
-
logger.debug("Airgap min/max from center: %s/%s", min_dist, max_dist)
|
4442
|
-
for a in areas:
|
4443
|
-
logger.debug("%s: min/max from center: %s/%s", a.identifier(), a.min_dist, a.max_dist)
|
4444
|
-
logger.debug("%s: min/max x: %s/%s, y: %s/%s",
|
4445
|
-
a.identifier(),
|
4446
|
-
a.min_x, a.max_x,
|
4447
|
-
a.min_y, a.max_y)
|
4448
|
-
if less_equal(a.min_x, -min_dist) and greater_equal(a.max_x, min_dist) and \
|
4449
|
-
less_equal(a.min_y, -min_dist) and greater_equal(a.max_y, min_dist):
|
4450
|
-
logger.debug("%s: around center", a.identifier())
|
4451
|
-
continue
|
4452
|
-
if np.isclose(a.min_dist, min_dist, rtol=1e-3, atol=1e-2):
|
4453
|
-
continue
|
4454
|
-
if less_equal(a.max_dist, max_dist, rtol=1e-3, atol=1e-2):
|
4455
|
-
return False
|
4456
|
-
|
4457
|
-
return builder.close_outer_winding_areas()
|
4458
|
-
|
4459
4484
|
def adjust_outer_hull_for_symmetry(self):
|
4460
4485
|
logger.debug("adjust_outer_hull_for_symmetry()")
|
4461
4486
|
areas = self.list_of_areas()
|
femagtools/dxfsl/machine.py
CHANGED
@@ -646,7 +646,7 @@ class Machine(object):
|
|
646
646
|
self.geom.set_virtual_start_end_corners()
|
647
647
|
|
648
648
|
self.geom.looking_for_corners()
|
649
|
-
create_areas = self.geom.
|
649
|
+
create_areas = self.geom.close_outer_winding_areas()
|
650
650
|
if self.geom.adjust_outer_hull_for_symmetry():
|
651
651
|
create_areas = True
|
652
652
|
|
@@ -1284,6 +1284,30 @@ class Machine(object):
|
|
1284
1284
|
def search_critical_elements(self, mindist):
|
1285
1285
|
self.geom.search_critical_elements(mindist)
|
1286
1286
|
|
1287
|
+
def create_arc_element(self,
|
1288
|
+
radius,
|
1289
|
+
startangle,
|
1290
|
+
endangle):
|
1291
|
+
arc = Arc(Element(center=self.center,
|
1292
|
+
radius=radius,
|
1293
|
+
start_angle=startangle*180/np.pi,
|
1294
|
+
end_angle=endangle*180/np.pi),
|
1295
|
+
color='darkred',
|
1296
|
+
linestyle='dotted')
|
1297
|
+
|
1298
|
+
node1 = self.geom.find_the_node(arc.p1)
|
1299
|
+
if node1 is None:
|
1300
|
+
self.geom.split_with_point(arc.p1)
|
1301
|
+
node1 = self.geom.find_the_node(arc.p1)
|
1302
|
+
node2 = self.geom.find_the_node(arc.p2)
|
1303
|
+
if node2 is None:
|
1304
|
+
self.geom.split_with_point(arc.p2)
|
1305
|
+
node2 = self.geom.find_the_node(arc.p2)
|
1306
|
+
assert(node1 is not None)
|
1307
|
+
assert(node2 is not None)
|
1308
|
+
logger.debug("ARC Node1=%s, Node2=%s", node1, node2)
|
1309
|
+
self.geom.add_element(arc, rtol=1e-3, atol=1e-3)
|
1310
|
+
|
1287
1311
|
def create_arc(self, radius,
|
1288
1312
|
color='red', linestyle='dotted',
|
1289
1313
|
attr=None):
|
@@ -1344,6 +1368,79 @@ class Machine(object):
|
|
1344
1368
|
self.endangle)
|
1345
1369
|
return self.geom.possible_magnet_in_the_middle(midangle)
|
1346
1370
|
|
1371
|
+
def separate_tooth_and_yoke(self, midangle):
|
1372
|
+
logger.debug("begin separate_tooth_and_yoke")
|
1373
|
+
wdg_list = self.geom.get_areas_of_type((AREA.TYPE_WINDINGS,))
|
1374
|
+
wdg_max_dist = 0.0
|
1375
|
+
wdg = None
|
1376
|
+
for w in wdg_list:
|
1377
|
+
if w.max_dist > wdg_max_dist:
|
1378
|
+
wdg_max_dist = w.max_dist
|
1379
|
+
wdg = w
|
1380
|
+
|
1381
|
+
tooth_list = self.geom.get_areas_of_type((AREA.TYPE_TOOTH,))
|
1382
|
+
tooth_max_dist = 0.0
|
1383
|
+
for tooth in tooth_list:
|
1384
|
+
tooth_max_dist = max(tooth_max_dist, tooth.max_dist)
|
1385
|
+
tooth_height = tooth_max_dist - self.geom.min_radius
|
1386
|
+
wdg_height = wdg_max_dist - self.geom.min_radius
|
1387
|
+
|
1388
|
+
logger.debug("HEIGHT TOOTH=%s, WINDINGS=%s", tooth_height, wdg_height)
|
1389
|
+
|
1390
|
+
if greater_equal(tooth_height, wdg_height * 0.9) and \
|
1391
|
+
less_equal(tooth_height, wdg_height * 1.1):
|
1392
|
+
logger.debug("Tooths are ok")
|
1393
|
+
return False # tooth ok
|
1394
|
+
|
1395
|
+
iron_list = self.geom.get_areas_of_irons()
|
1396
|
+
tooth_list = [iron for iron in iron_list
|
1397
|
+
if iron.close_to_ag and greater(iron.max_dist, wdg_max_dist, rtol=1e-2, atol=1e-2)]
|
1398
|
+
logger.debug("max winding dist = %s", wdg_max_dist)
|
1399
|
+
logger.debug("tooths = %s", len(tooth_list))
|
1400
|
+
wdg_nodes = [(distance(self.center, n), n) for n in wdg.list_of_nodes()]
|
1401
|
+
wdg_nodes.sort(reverse=True)
|
1402
|
+
|
1403
|
+
top_nodes = []
|
1404
|
+
other_nodes = []
|
1405
|
+
for d, n in wdg_nodes:
|
1406
|
+
if np.isclose(d, wdg.max_dist, rtol=1e-2, atol=1e-1):
|
1407
|
+
top_nodes.append((alpha_line(self.center, n), d, n))
|
1408
|
+
else:
|
1409
|
+
other_nodes.append((d, alpha_line(self.center, n), n))
|
1410
|
+
|
1411
|
+
a_right, d_right, n_right = (None, None, None)
|
1412
|
+
a_left, d_left, n_left = (None, None, None)
|
1413
|
+
|
1414
|
+
if not top_nodes:
|
1415
|
+
other_nodes.sort(reverse=True)
|
1416
|
+
for d, a, n in other_nodes:
|
1417
|
+
if a > midangle:
|
1418
|
+
if not a_left:
|
1419
|
+
a_left = a
|
1420
|
+
d_left = d
|
1421
|
+
n_left = n
|
1422
|
+
else:
|
1423
|
+
if not a_right:
|
1424
|
+
a_right = a
|
1425
|
+
d_right = d
|
1426
|
+
n_right = n
|
1427
|
+
if a_left and a_right:
|
1428
|
+
break
|
1429
|
+
if not (a_left and a_right):
|
1430
|
+
logger.debug("end separate_tooth_and_yoke: no arcs possible")
|
1431
|
+
return False # bad luck
|
1432
|
+
else:
|
1433
|
+
top_nodes.sort()
|
1434
|
+
a_right, d_right, n_right = top_nodes[0]
|
1435
|
+
a_left, d_left, n_left = top_nodes[0-1]
|
1436
|
+
node_right = self.geom.find_the_node(n_right)
|
1437
|
+
node_left = self.geom.find_the_node(n_left)
|
1438
|
+
|
1439
|
+
self.create_arc_element(d_right, self.startangle, a_right)
|
1440
|
+
self.create_arc_element(d_left, a_left, self.endangle)
|
1441
|
+
logger.debug("end separate_tooth_and_yoke")
|
1442
|
+
return True
|
1443
|
+
|
1347
1444
|
def create_mirror_lines_outside_windings(self):
|
1348
1445
|
logger.debug("create_mirror_lines_outside_windings")
|
1349
1446
|
|
@@ -1351,6 +1448,9 @@ class Machine(object):
|
|
1351
1448
|
logger.debug("end create_mirror_lines_outside_windings: not done")
|
1352
1449
|
return
|
1353
1450
|
|
1451
|
+
midangle = middle_angle(self.startangle, self.endangle)
|
1452
|
+
self.separate_tooth_and_yoke(midangle)
|
1453
|
+
|
1354
1454
|
radius = self.radius+10
|
1355
1455
|
ag_list = self.geom.detect_airgaps(self.center,
|
1356
1456
|
self.startangle, self.endangle,
|
@@ -1359,7 +1459,6 @@ class Machine(object):
|
|
1359
1459
|
radius_list = [(ag[0], (ag[0] + ag[1]) / 2, ag[1]) for ag in ag_list]
|
1360
1460
|
radius_list.sort(reverse=True)
|
1361
1461
|
|
1362
|
-
midangle = middle_angle(self.startangle, self.endangle)
|
1363
1462
|
line = Line(
|
1364
1463
|
Element(start=self.center,
|
1365
1464
|
end=point(self.center, radius, midangle)))
|
femagtools/isa7.py
CHANGED
@@ -1359,28 +1359,31 @@ class Isa7(object):
|
|
1359
1359
|
# prep dictionary for the loss calculation
|
1360
1360
|
pm_data = []
|
1361
1361
|
for i, se in enumerate(mag_spels):
|
1362
|
-
|
1363
|
-
|
1364
|
-
|
1365
|
-
|
1366
|
-
|
1367
|
-
|
1368
|
-
|
1369
|
-
|
1370
|
-
|
1371
|
-
|
1372
|
-
|
1373
|
-
|
1374
|
-
|
1375
|
-
|
1376
|
-
|
1377
|
-
|
1378
|
-
|
1379
|
-
|
1380
|
-
|
1381
|
-
|
1382
|
-
|
1383
|
-
|
1362
|
+
try:
|
1363
|
+
ecp = [e.center for e in se.elements]
|
1364
|
+
geometry = se.get_rect_geom()
|
1365
|
+
|
1366
|
+
#= np.moveaxis(bxy, 1, 0)
|
1367
|
+
pd = dict(name='pm_data_se' + str(se.key),
|
1368
|
+
hm=geometry['h'],
|
1369
|
+
wm=geometry['w'],
|
1370
|
+
lm=self.arm_length,
|
1371
|
+
alpha=geometry['alpha'],
|
1372
|
+
ls=self.arm_length,
|
1373
|
+
sigma=cond,
|
1374
|
+
mur=mur,
|
1375
|
+
loadcase=ibeta,
|
1376
|
+
numpoles=poles,
|
1377
|
+
elcp=transform_coord(geometry, ecp),
|
1378
|
+
area=se.area(),
|
1379
|
+
spel_key=se.key)
|
1380
|
+
if ibeta != None:
|
1381
|
+
pd.update({'bl': self.get_magnet_flux_density(se, icur, ibeta)})
|
1382
|
+
pd.update(pos)
|
1383
|
+
|
1384
|
+
pm_data.append(pd)
|
1385
|
+
except IndexError as e:
|
1386
|
+
logger.warning("se %d magnet geometry ignored: %s", i, e)
|
1384
1387
|
return pm_data
|
1385
1388
|
|
1386
1389
|
def get_magnet_flux_density(self, se, icur, ibeta) -> list:
|
femagtools/machine/__init__.py
CHANGED
@@ -32,7 +32,7 @@ def create_from_eecpars(temp, eecpars, lfe=1, wdg=1):
|
|
32
32
|
PM, EESM or IM"""
|
33
33
|
rlfe = lfe
|
34
34
|
rwdg = wdg
|
35
|
-
opts = {k: eecpars[k] for k in ('zeta1', 'gam', 'kh', 'kpfe',
|
35
|
+
opts = {k: eecpars[k] for k in ('zeta1', 'gam', 'kh', 'kpfe', 'kpfe_s', 'kpfe_r',
|
36
36
|
'kfric_b', 'kpmag') if k in eecpars}
|
37
37
|
try:
|
38
38
|
opts['rotor_mass'] = rlfe*eecpars['rotor_mass']
|
@@ -51,7 +51,7 @@ def create_from_eecpars(temp, eecpars, lfe=1, wdg=1):
|
|
51
51
|
smpars = copy.deepcopy(eecpars)
|
52
52
|
smpars['tcu1'] = temp[0]
|
53
53
|
smpars['tcu2'] = temp[1]
|
54
|
-
# external inductances
|
54
|
+
# external inductances
|
55
55
|
opts["ls"] = eecpars.get('ls1', 0)*rwdg**2
|
56
56
|
if 'ldq' in smpars:
|
57
57
|
machine = SynchronousMachineLdq(smpars, lfe=rlfe, wdg=rwdg, **opts)
|
femagtools/machine/effloss.py
CHANGED
@@ -372,6 +372,10 @@ def efficiency_losses_map(eecpars, u1, T, temp, n, npoints=(60, 40),
|
|
372
372
|
if isinstance(m, PmRelMachine):
|
373
373
|
plfe1 = m.kpfe*m.iqd_plfe1(*iqd, f1)
|
374
374
|
plfe2 = m.kpfe*m.iqd_plfe2(iqd[0], iqd[1], f1)
|
375
|
+
if hasattr(m, 'kpfe_s'):
|
376
|
+
plfe1 = m.kpfe_s*m.iqd_plfe1(*iqd, f1)
|
377
|
+
if hasattr(m, 'kpfe_r'):
|
378
|
+
plfe2 = m.kpfe_r*m.iqd_plfe2(iqd[0], iqd[1], f1)
|
375
379
|
plmag = m.kpmag*m.iqd_plmag(iqd[0], iqd[1], f1)
|
376
380
|
plcu1 = m.iqd_plcu1(iqd[0], iqd[1], 2*np.pi*f1)
|
377
381
|
plcu2 = m.iqd_plcu2(*iqd)
|
@@ -385,6 +389,10 @@ def efficiency_losses_map(eecpars, u1, T, temp, n, npoints=(60, 40),
|
|
385
389
|
elif isinstance(m, SynchronousMachine):
|
386
390
|
plfe1 = m.kpfe*m.iqd_plfe1(*iqd, f1)
|
387
391
|
plfe2 = m.kpfe*m.iqd_plfe2(*iqd, f1)
|
392
|
+
if hasattr(m, 'kpfe_s'):
|
393
|
+
plfe1 = m.kpfe_s*m.iqd_plfe1(*iqd, f1)
|
394
|
+
if hasattr(m, 'kpfe_r'):
|
395
|
+
plfe2 = m.kpfe_r*m.iqd_plfe2(*iqd, f1)
|
388
396
|
plmag = np.zeros_like(plfe2)
|
389
397
|
plcu1 = m.iqd_plcu1(iqd[0], iqd[1], f1)
|
390
398
|
try:
|
femagtools/machine/pm.py
CHANGED
@@ -97,7 +97,7 @@ class PmRelMachine(object):
|
|
97
97
|
self.zeta1 = 0.2
|
98
98
|
self.gam = 0.7
|
99
99
|
self.kh = 2
|
100
|
-
self.kpfe = 1 # iron loss factor
|
100
|
+
self.kpfe = 1 # common iron loss factor
|
101
101
|
self.kpmag = 1 # magnet loss factor
|
102
102
|
self.kfric_b = 1
|
103
103
|
self.rotor_mass = 0
|
@@ -258,7 +258,13 @@ class PmRelMachine(object):
|
|
258
258
|
and friction windage losses"""
|
259
259
|
if n > 1e-3:
|
260
260
|
f1 = self.p*n
|
261
|
-
|
261
|
+
plfe1 = self.kpfe * self.iqd_plfe1(iq, id, f1)
|
262
|
+
plfe2 = self.kpfe * self.iqd_plfe2(iq, id, f1)
|
263
|
+
if hasattr(self, 'kpfe_s'):
|
264
|
+
plfe1 = self.kpfe_s * self.iqd_plfe1(iq, id, f1)
|
265
|
+
if hasattr(self, 'kpfe_r'):
|
266
|
+
plfe2 = self.kpfe_r * self.iqd_plfe2(iq, id, f1)
|
267
|
+
plfe = plfe1 + plfe2
|
262
268
|
pmag = self.kpmag * self.iqd_plmag(iq, id, f1)
|
263
269
|
return (plfe + pmag + self.pfric(n))/(2*np.pi*n)
|
264
270
|
return 0
|
@@ -927,10 +933,10 @@ class PmRelMachine(object):
|
|
927
933
|
plfe1 = self.iqd_plfe1(iq, id, f1)
|
928
934
|
plfe2 = self.iqd_plfe2(iq, id, f1)
|
929
935
|
plmag = self.iqd_plmag(iq, id, f1)
|
930
|
-
plfe = plfe1 + plfe2
|
936
|
+
plfe = plfe1 + plfe2
|
931
937
|
plfric = self.pfric(n)
|
932
938
|
plcu = self.betai1_plcu(i1, 2 * np.pi * f1)
|
933
|
-
pltotal = plfe + plcu + plfric
|
939
|
+
pltotal = plfe + plcu + plfric + plmag
|
934
940
|
p1 = pmech + pltotal
|
935
941
|
if np.abs(pmech) < 1e-12:
|
936
942
|
eta = 0 # power to low for eta calculation
|
@@ -1153,11 +1159,15 @@ class PmRelMachine(object):
|
|
1153
1159
|
f1 = np.array(r['n'])*self.p
|
1154
1160
|
plfe1 = self.kpfe*self.iqd_plfe1(np.array(r['iq']), np.array(r['id']), f1)
|
1155
1161
|
plfe2 = self.kpfe*self.iqd_plfe2(np.array(r['iq']), np.array(r['id']), f1)
|
1162
|
+
if hasattr(self, 'kpfe_s'):
|
1163
|
+
plfe1 = self.kpfe_s*self.iqd_plfe1(np.array(r['iq']), np.array(r['id']), f1)
|
1164
|
+
if hasattr(self, 'kpfe_r'):
|
1165
|
+
plfe2 = self.kpfe_r*self.iqd_plfe2(np.array(r['iq']), np.array(r['id']), f1)
|
1156
1166
|
plmag = self.kpmag*self.iqd_plmag(np.array(r['iq']), np.array(r['id']), f1)
|
1157
|
-
plfe = plfe1 + plfe2
|
1167
|
+
plfe = plfe1 + plfe2
|
1158
1168
|
plcu = self.betai1_plcu(np.array(r['i1']), 2*np.pi*f1)
|
1159
1169
|
plfw = self.pfric(2*np.pi*f1)
|
1160
|
-
pltotal = plfe + plcu + plfw
|
1170
|
+
pltotal = plfe + plcu + plfw + plmag
|
1161
1171
|
r['pmech'] = pmech.tolist()
|
1162
1172
|
r['plfe'] = plfe.tolist()
|
1163
1173
|
r['plcu'] = plcu.tolist()
|
femagtools/machine/sm.py
CHANGED
@@ -22,7 +22,7 @@ eecdefaults = {
|
|
22
22
|
'tcu2': 20,
|
23
23
|
'rotor_mass': 0,
|
24
24
|
'kfric_b': 1,
|
25
|
-
'kpfe': 1 # iron loss factor
|
25
|
+
'kpfe': 1 # common iron loss factor
|
26
26
|
}
|
27
27
|
|
28
28
|
logger = logging.getLogger('sm')
|
@@ -76,7 +76,13 @@ def parident(workdir, engine, machine,
|
|
76
76
|
raise ValueError('i1_max missing')
|
77
77
|
i1_max = kwargs['i1_max']
|
78
78
|
|
79
|
-
|
79
|
+
|
80
|
+
if "magnetFsl" in machine["magnet"]:
|
81
|
+
rotorkey = "magnet"
|
82
|
+
else:
|
83
|
+
rotorkey = "rotor"
|
84
|
+
|
85
|
+
ifnom = machine[rotorkey]['ifnom']
|
80
86
|
exc_logspace = True
|
81
87
|
ifmin, ifmax = ifnom/4, 1.4*ifnom
|
82
88
|
if exc_logspace:
|
@@ -197,7 +203,7 @@ def parident(workdir, engine, machine,
|
|
197
203
|
if simulation['calculationMode'] == 'ld_lq_fast':
|
198
204
|
dqpars = dict(m=3, p=b['machine']['p'],
|
199
205
|
r1=float(r1),
|
200
|
-
r2=machine[
|
206
|
+
r2=machine[rotorkey].get('resistance', 1),
|
201
207
|
rotor_mass=rotor_mass, kfric_b=1,
|
202
208
|
ldq=[dict(
|
203
209
|
ex_current=b['machine']['ex_current'],
|
@@ -214,7 +220,7 @@ def parident(workdir, engine, machine,
|
|
214
220
|
else:
|
215
221
|
dqpars = dict(m=3, p=b['machine']['p'],
|
216
222
|
r1=r1,
|
217
|
-
r2=machine[
|
223
|
+
r2=machine[rotorkey].get('resistance', 1),
|
218
224
|
rotor_mass=rotor_mass, kfric_b=1,
|
219
225
|
psidq=[dict(
|
220
226
|
ex_current=b['machine']['ex_current'],
|
@@ -387,8 +393,13 @@ class SynchronousMachine(object):
|
|
387
393
|
and friction windage losses"""
|
388
394
|
if n > 1e-3:
|
389
395
|
f1 = self.p*n
|
390
|
-
|
391
|
-
|
396
|
+
plfe1 = self.kpfe * self.iqd_plfe1(iq, id, iex, f1)
|
397
|
+
plfe2 = self.kpfe * self.iqd_plfe2(iq, id, iex, f1)
|
398
|
+
if hasattr(self, 'kpfe_s'):
|
399
|
+
plfe1 = self.kpfe_s * self.iqd_plfe1(iq, id, iex, f1)
|
400
|
+
if hasattr(self, 'kpfe_r'):
|
401
|
+
plfe2 = self.kpfe_r * self.iqd_plfe2(iq, id, iex, f1)
|
402
|
+
plfe = plfe1 + plfe2
|
392
403
|
return (plfe + self.pfric(n))/(2*np.pi*n)
|
393
404
|
return 0
|
394
405
|
|
femagtools/mcv.py
CHANGED
@@ -1173,7 +1173,10 @@ class MagnetizingCurve(object):
|
|
1173
1173
|
mcv = self.find_by_name(name)
|
1174
1174
|
if not mcv:
|
1175
1175
|
bname = name
|
1176
|
-
filename =
|
1176
|
+
filename = name if pathlib.Path(name).suffix.upper() == ext \
|
1177
|
+
else ''.join((name, ext))
|
1178
|
+
if name == 'dummy':
|
1179
|
+
return filename
|
1177
1180
|
# check fillfac and readmcv
|
1178
1181
|
if not fillfac or fillfac == 1.0:
|
1179
1182
|
try:
|
femagtools/shortcircuit.py
CHANGED
@@ -108,11 +108,11 @@ def shortcircuit(femag, machine, bch, simulation, engine=0):
|
|
108
108
|
bchsc.scData['demag'] = bchsc.demag
|
109
109
|
if simulation.get('sim_demagn', 0):
|
110
110
|
dd = {'displ': [d['displ']
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
111
|
+
for d in bchsc.demag if 'displ' in d],
|
112
|
+
'H_max': [d['H_max']
|
113
|
+
for d in bchsc.demag if 'H_max' in d],
|
114
|
+
'H_av': [d['H_av']
|
115
|
+
for d in bchsc.demag if 'H_av' in d]}
|
116
116
|
x1 = bchsc.demag[0]['current_1']
|
117
117
|
x2 = bchsc.demag[0]['current_2']
|
118
118
|
def func(phi):
|
@@ -121,6 +121,7 @@ def shortcircuit(femag, machine, bch, simulation, engine=0):
|
|
121
121
|
i1max = x1/np.cos(phi)
|
122
122
|
|
123
123
|
phirot = dd['displ'][0]/180*np.pi
|
124
|
+
logger.info("i1max %g phi %g phirot %g", i1max, phi, phirot)
|
124
125
|
bchsc.scData['demag'] = demag(
|
125
126
|
femag, machine, simulation,
|
126
127
|
i1max, phirot, phi, engine)
|
@@ -319,7 +320,7 @@ def shortcircuit_2phase(femag, machine, simulation, engine=0):
|
|
319
320
|
# rotor position at maximum current:
|
320
321
|
trot = min(iav[0], iap[0])
|
321
322
|
phirot = wm*trot + phi0
|
322
|
-
logger.
|
323
|
+
logger.debug("phirot %.1f", phirot)
|
323
324
|
|
324
325
|
scData = {
|
325
326
|
'ia': ia.tolist(),
|
@@ -345,7 +346,7 @@ def demag(femag, machine, simulation, i1max, phirot, phi, engine=0):
|
|
345
346
|
"""demag simulation using psi-torq-rem-rot"""
|
346
347
|
logger.info("Demagnetization processing")
|
347
348
|
i1min = simulation.get('i1min', abs(i1max/3))
|
348
|
-
num_steps = 7
|
349
|
+
num_steps = simulation.get('num_demag_cur_steps', 7)
|
349
350
|
b = (i1min-abs(i1max))/np.log(i1min/abs(i1max))
|
350
351
|
a = abs(i1max)/b
|
351
352
|
xtab = np.linspace(i1min/abs(i1max),
|
@@ -82,14 +82,14 @@ rotate({
|
|
82
82
|
mode = "save" -- save initial model state
|
83
83
|
})
|
84
84
|
|
85
|
+
rotate({angle=phi, mode="absolute"})
|
86
|
+
|
85
87
|
file_psi = io.open("psi-torq-rem.dat","w")
|
86
88
|
for i=1, #curvec do
|
87
|
-
print(string.format(" current: %d/%d %g, %g, %g\n",
|
88
|
-
i, #curvec, curvec[i][1], curvec[i][2], curvec[i][3]))
|
89
|
-
|
90
|
-
rotate({angle=phi, mode="absolute"})
|
91
89
|
psi, tq, rr = calc_flux_torq_rem(curvec[i])
|
92
90
|
|
91
|
+
print(string.format(" current: %d/%d %g, %g, %g torque %g rr %g\n",
|
92
|
+
i, #curvec, curvec[i][1], curvec[i][2], curvec[i][3], tq, rr))
|
93
93
|
file_psi:write(string.format("%g ", phi))
|
94
94
|
for k=1, 3 do
|
95
95
|
file_psi:write(string.format("%g ", curvec[i][k]))
|
@@ -0,0 +1,43 @@
|
|
1
|
+
|
2
|
+
m.yoke_diam = dy1
|
3
|
+
m.inside_diam = da1
|
4
|
+
|
5
|
+
m.wdg_location = -1 -- for gen_windings
|
6
|
+
|
7
|
+
m.slot_angle = ${model['slot_angle']*1e3}
|
8
|
+
m.slot_height = ${model['slot_height']*1e3}
|
9
|
+
m.slot_h1 = ${model['slot_h1']*1e3}
|
10
|
+
m.slot_h2 = ${model['slot_h2']*1e3}
|
11
|
+
m.slot_bk = ${model['slot_bk']*1e3}
|
12
|
+
m.slot_width = ${model['slot_width']*1e3}
|
13
|
+
m.slot_r1 = ${model['slot_r1']*1e3}
|
14
|
+
m.slot_r2 = ${model['slot_r2']*1e3}
|
15
|
+
m.middle_line = ${model.get('middle_line',0)}
|
16
|
+
m.tooth_width = ${model.get('tooth_width',0)*1e3}
|
17
|
+
m.slot_topwidth = ${model.get('slot_topwidth',0)*1e3}
|
18
|
+
|
19
|
+
m.zeroangl = ${model.get('zeroangle',0)}
|
20
|
+
m.rlength = ${model.get('rlength',1)*100}
|
21
|
+
|
22
|
+
% if model.get('ac_loss', False):
|
23
|
+
m.ac_loss = ${model.get('ac_loss', 6)}
|
24
|
+
% endif
|
25
|
+
m.mcvkey_yoke = mcvkey_yoke
|
26
|
+
|
27
|
+
pre_models("STATOR_KS1")
|
28
|
+
|
29
|
+
if mcvkey_teeth ~= nil then
|
30
|
+
if m.inside_diam > m.yoke_diam then
|
31
|
+
r = (m.inside_diam - m.slot_height)/2
|
32
|
+
else
|
33
|
+
r = (m.inside_diam + m.slot_height)/2
|
34
|
+
end
|
35
|
+
x0, y0 = pr2c(r, 2*math.pi/m.tot_num_slot + m.zeroangl/180*math.pi)
|
36
|
+
def_mat_fm_nlin(x0, y0, "blue", mcvkey_teeth, m.rlength)
|
37
|
+
end
|
38
|
+
|
39
|
+
%if model.get('thcond', 0) and model.get('thcap', 0):
|
40
|
+
stator_thcond = ${model.get('thcond', 24)}
|
41
|
+
stator_thcap = ${model.get('thcap', 480)}
|
42
|
+
stator_density = ${model.get('density', 7700)}
|
43
|
+
%endif
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: femagtools
|
3
|
-
Version: 1.8.
|
3
|
+
Version: 1.8.19
|
4
4
|
Summary: Python API for FEMAG
|
5
5
|
Author-email: Ronald Tanner <tar@semafor.ch>, Dapu Zhang <dzhang@gtisoft.com>, Beat Holm <hob@semafor.ch>, Günther Amsler <amg@semafor.ch>, Nicolas Mauchle <mau@semafor.ch>
|
6
6
|
License: Copyright (c) 2016-2023, Semafor Informatik & Energie AG, Basel
|
@@ -1,9 +1,9 @@
|
|
1
|
-
femagtools/__init__.py,sha256=
|
1
|
+
femagtools/__init__.py,sha256=k1SL4nzTdLCU7dFO7Qd0V59z23xi1pUBL0lTp770Lho,1601
|
2
2
|
femagtools/airgap.py,sha256=ROm4uhZjYiO0CxmFnpgiaNY9x3khlO8LBLmp5Yh5RLk,1973
|
3
3
|
femagtools/amazon.py,sha256=O1ICuv21XDAJi1qK1Sigs2TdS6hDZP19OzvmE2t76wU,12069
|
4
4
|
femagtools/amela.py,sha256=2q-Xsj6i6nQ3iKheBR1vQ4FulJfF1i-L8w3a3U8GYWo,4362
|
5
5
|
femagtools/asm.py,sha256=CiL0KWaF4P7O6-VwmGLdva_icwmPrPiI-TFQ19XYTKk,7660
|
6
|
-
femagtools/bch.py,sha256=
|
6
|
+
femagtools/bch.py,sha256=RHdQreeO2KuJaAVTXy2OUOgPGyHMtLlnKqYjPnZJRuY,76757
|
7
7
|
femagtools/bchxml.py,sha256=KrRjAdrUPZXmiWvonu9HhpG_NvImMBpiXWTL4iSr4kE,3142
|
8
8
|
femagtools/condor.py,sha256=J8z9iBdvrGu3I1eFNoyKV8AXzRoTEPGLSak6cXUQxAM,10766
|
9
9
|
femagtools/conductor.py,sha256=rXO7c7Qh_s7JpgILmLd4IbG64vP6Eh143YF9u25Mdwg,1076
|
@@ -24,13 +24,13 @@ femagtools/google.py,sha256=ugRyHY1zBjHR4aNfbA7GeF-ZU_NgleuVTZaWpi_XLT4,17144
|
|
24
24
|
femagtools/grid.py,sha256=s7LfKKLm2H4-cza2kSEANq6vwxq10Su3TJl3kHShHRA,1561
|
25
25
|
femagtools/heat_source_network.py,sha256=dz3nTK084SR2fyy1167wlpBlGrzv54OqCCGKPNWqpsU,16836
|
26
26
|
femagtools/hxy.py,sha256=PkiZ_-CRhtvtpkmLAP8iMtwvzh7CjKGGcAbOhFb4Nls,6275
|
27
|
-
femagtools/isa7.py,sha256=
|
27
|
+
femagtools/isa7.py,sha256=_bJzDLDTAt6qiXks5UF-xdTuuSjMebmSPiQvB6KJzdE,68552
|
28
28
|
femagtools/jhb.py,sha256=stJxkmzHpfUIBVcFw7jWbV5KN9_EFqzOCgacyhUqWvM,1779
|
29
29
|
femagtools/job.py,sha256=sh4yk8RVEFai7YDBMsVg19p9xEd6_sfyNX5WQSY7HEY,11726
|
30
30
|
femagtools/leakinduc.py,sha256=4IGZaV8S1ZG6L3hgZsCXqMsMNRH4F88l9EsvUjSXDSE,999
|
31
31
|
femagtools/losscoeffs.py,sha256=7B29VdEsmv8HSP749X3QBb_E-XN6Z9dvNleKiRLWaMI,7721
|
32
32
|
femagtools/magnet.py,sha256=Nuk060bT4Wa3lX74HdefqTTtUxLaERDSBYTTpbi6KP4,1093
|
33
|
-
femagtools/mcv.py,sha256=
|
33
|
+
femagtools/mcv.py,sha256=ICXXbF5KGUsi91HktYuxzKcII-i96aBXkJzNtwkLy1Q,48740
|
34
34
|
femagtools/me.py,sha256=z6RJkvSbgMmorCQTxKvq44uIYKh82uYYExjkNePJCmE,1813
|
35
35
|
femagtools/model.py,sha256=dk9x-iqRzgOTdTCeU_ynUZGb1bt4FvU1ZGMPXytMbUg,17965
|
36
36
|
femagtools/moproblem.py,sha256=kOP8pRdD8YXz28_M2WKnFgl3eeJ7tqg49ohoazsmUOg,2825
|
@@ -43,7 +43,7 @@ femagtools/opt.py,sha256=wBU0yh3hZlNti_zfIvtKcPg1EJrnE3I1BqmVxLGWixU,8753
|
|
43
43
|
femagtools/parstudy.py,sha256=eHOcHHZAQMPnYwyQpnX9daZIMKhZZl8aDeEPXBgSS-k,20550
|
44
44
|
femagtools/poc.py,sha256=yPWmpi8Q2g7NmpAi2YV5ezyo0VUj67EK0tcX2wikerw,7207
|
45
45
|
femagtools/semi_fea.py,sha256=WZtYKrzhDruETyuEW2kpiNp9OaA7Hheq3qJiAIYtsjg,3475
|
46
|
-
femagtools/shortcircuit.py,sha256=
|
46
|
+
femagtools/shortcircuit.py,sha256=9wulzRQamfgbRdjH90eukqjuxOgO6UU2m97W7LkGFP8,14734
|
47
47
|
femagtools/tks.py,sha256=mDi45S5go9-jwALh6rS9RWPoOFBORZm0-XL4ECjSf_8,7531
|
48
48
|
femagtools/ts.py,sha256=yoYjpKrr_0b-tHfsX5azJEBXHUs9PN8P-SMhbjjRhCA,48381
|
49
49
|
femagtools/utils.py,sha256=G9U-C8ULcdGq9Ix6VEtDZ9dw7hjJHBjG3Otlka4wmU0,1787
|
@@ -52,31 +52,31 @@ femagtools/vtu.py,sha256=Sf83dHIfCKY2km-MIUHKKoj-JKN4PDX7kkPLZXyIYY4,10723
|
|
52
52
|
femagtools/windings.py,sha256=eGRoDbi9yruiWHqZysamBLPJefw8IQX3Lq4KpG4oIKo,28216
|
53
53
|
femagtools/zmq.py,sha256=62x5VRk0TMNER0-EZ8E28IdLKzsttlbxy1U_3wocNLc,9618
|
54
54
|
femagtools/dxfsl/__init__.py,sha256=MywcCdpKPKs4qJBJJgeDsikJFJ2P48dbTuNk303f5pM,76
|
55
|
-
femagtools/dxfsl/area.py,sha256=
|
56
|
-
femagtools/dxfsl/areabuilder.py,sha256
|
55
|
+
femagtools/dxfsl/area.py,sha256=ccRBlD3IeZOW5oiu23ROhtfnpx1LpjQ_E7MbV_HoArU,70646
|
56
|
+
femagtools/dxfsl/areabuilder.py,sha256=H416_u2796F8nJwqa6EI2gCw-5Ay7cCpRRz3_39u42k,37916
|
57
57
|
femagtools/dxfsl/concat.py,sha256=F6scwesxyOmfmKQ5kGspNCxA71Yz6QgxFL7lTj3hsaI,13385
|
58
58
|
femagtools/dxfsl/conv.py,sha256=rAG_r2twWtcZyLKe8L8gYcC-n-JMG-dK1iMmd9yviTQ,12237
|
59
|
-
femagtools/dxfsl/converter.py,sha256=
|
59
|
+
femagtools/dxfsl/converter.py,sha256=LCzKF9dAKywJcjCPCavSM2jxilyO6R_kDMdctF4KRJE,41695
|
60
60
|
femagtools/dxfsl/corner.py,sha256=-XPBcnEau-2-SRHLYzlBqCQGaFfgm_DH2qR1mSaFoAs,1311
|
61
61
|
femagtools/dxfsl/dumprenderer.py,sha256=n4AvInjvGIaC2iKZtQaYXXDyJVSQ3uEOFOLD4-xfKRY,1861
|
62
62
|
femagtools/dxfsl/dxfparser.py,sha256=kyXG0kZfNyOgn96MqBgP8RhOQhppfB5NbyRNNybs1C0,13451
|
63
63
|
femagtools/dxfsl/femparser.py,sha256=O8940Q1Mz8MKng6W8M3s9KfTvhDLJ56tfQWtZEW3xMM,2134
|
64
|
-
femagtools/dxfsl/fslrenderer.py,sha256=
|
64
|
+
femagtools/dxfsl/fslrenderer.py,sha256=L8qymxhrxDvNg9LLwAQgDXM1EU3yA1L3BoYpkenECEs,28005
|
65
65
|
femagtools/dxfsl/functions.py,sha256=1RFT2YPR_rTJSKtTqIoO8Z-s_kXKIp95zed83SM0gZg,12784
|
66
|
-
femagtools/dxfsl/geom.py,sha256=
|
66
|
+
femagtools/dxfsl/geom.py,sha256=d-HU4yV6j9RA8PeIvesMDvXBc4xIrKXphmBI2e3_QxA,186927
|
67
67
|
femagtools/dxfsl/journal.py,sha256=r4z52av3k95MjwzypgUJpj8sSAeQoJsS81Uqs1IBLVw,4265
|
68
|
-
femagtools/dxfsl/machine.py,sha256=
|
68
|
+
femagtools/dxfsl/machine.py,sha256=wtUqLAmq4Imd6uoPwrhZ5h0MCku3Mihrpqx7QycFYng,63062
|
69
69
|
femagtools/dxfsl/plotrenderer.py,sha256=q2cORuxJEf1Ws6oCY9c0gF6N3kDrcI6WOz3u5Vl6R_c,13823
|
70
70
|
femagtools/dxfsl/shape.py,sha256=uQqbgXIA2_KP2XRdhCfVfGWjcjwzhJ5t9RhiqR9R98c,61668
|
71
71
|
femagtools/dxfsl/svgparser.py,sha256=RY2TU9MK6gOaNmI6w6RNqcw7H9YGmK-NUwvdylKBcsE,3763
|
72
72
|
femagtools/dxfsl/symmetry.py,sha256=bGDSZhs6VOS-gp4C9eW0tjyMMec4BVFVZ0NpGXV3H0U,44660
|
73
|
-
femagtools/machine/__init__.py,sha256=
|
73
|
+
femagtools/machine/__init__.py,sha256=RjJdy1J_9-_FEvdqdBtIjGjqF93NRzDfU5VS-z_6ARI,7557
|
74
74
|
femagtools/machine/afpm.py,sha256=_Ei1FMuoC1GiI0z90qnyuxNrefkmeRdtDZKm20glzNY,40711
|
75
|
-
femagtools/machine/effloss.py,sha256=
|
75
|
+
femagtools/machine/effloss.py,sha256=jNgo9OGOnLRoZ6Mw2Lf8xOpAQWOBxX5HH4F-WzPOW0A,17687
|
76
76
|
femagtools/machine/im.py,sha256=5wYjsEQIiKR62M2M0rA8zmybWQDVjpoazXJPRKyQOvM,40331
|
77
|
-
femagtools/machine/pm.py,sha256=
|
77
|
+
femagtools/machine/pm.py,sha256=fKKNsnUQkO9_zz3-SC9u9OCjw3hw7Lj4FImB4ZlHrWQ,71040
|
78
78
|
femagtools/machine/sizing.py,sha256=QO-k-UALmSPFNf8ajJPDnzKtlbkiAhX1DqWCRLr-H9k,32306
|
79
|
-
femagtools/machine/sm.py,sha256=
|
79
|
+
femagtools/machine/sm.py,sha256=SwidHYI-BEGiZQMm9rYTnIuqJN121RgIQ9QetYl3fic,41066
|
80
80
|
femagtools/machine/utils.py,sha256=HRM9UHY0UwuBWyK2dAfwlPuvMkXYBVqHlmEsUIdSNJk,21694
|
81
81
|
femagtools/moo/__init__.py,sha256=zinmWEOrsEz6DmMX0Dbn4t6_1UR-p4bEGqyR1wUQk_Q,175
|
82
82
|
femagtools/moo/algorithm.py,sha256=e-Cgp2rp_hG9DXqWqluzQGNIWvCfthUgLD8O-aVPofA,5763
|
@@ -151,7 +151,7 @@ femagtools/templates/pm_sym_loss.mako,sha256=FNAvi_gmTXsGylrpi7lLKPoOOcNCV1mG6rc
|
|
151
151
|
femagtools/templates/prepare_thermal.mako,sha256=V3W6BGW7gjY8Lg2qzvGDi8rxx3JvPzrWoABDvHKyq54,9539
|
152
152
|
femagtools/templates/psd_psq_fast.mako,sha256=IOZx04JhVleAAbBOPWk9gEwDyT28z0zkF9tyEBteRPU,1428
|
153
153
|
femagtools/templates/psi-torq-rem-rot.mako,sha256=A1KOsYNSJhIJfumF-egnU-HUfNMPeX-XSPL_WsoE1Cw,3579
|
154
|
-
femagtools/templates/psi-torq-rem.mako,sha256=
|
154
|
+
femagtools/templates/psi-torq-rem.mako,sha256=2HnPoipTeb9I69ysvgidwdHR0DxBKPxr2W0YJEmwXoU,3121
|
155
155
|
femagtools/templates/psi-torq-rot.mako,sha256=_iT-IbgeC28wQzMVfi7uIN0cfp5pZ6d1mpLsoQrMx2c,2646
|
156
156
|
femagtools/templates/ring.mako,sha256=Cuc_FuCPWZM-g3TxHqzTdjknYEJSUgP-y64gp8pekDI,643
|
157
157
|
femagtools/templates/rot_hsm.mako,sha256=eh50TbpWNUALK9_7wOOJ7KPewHos7JExAfMACbPlXYc,973
|
@@ -166,13 +166,14 @@ femagtools/templates/stator2.mako,sha256=7Ae9sfaX7H4ummL6-g8iG42ArUvl6J809TW2tOd
|
|
166
166
|
femagtools/templates/stator3Linear.mako,sha256=pNe3C1wT0W2C0qePo3sEyebW1z_dpTuJzg0r5kf3JQY,760
|
167
167
|
femagtools/templates/stator4.mako,sha256=Jq8pfIuOmmpyGOL1z2aQZfbwMS5-Zyn6OGJ51LCBVKs,1179
|
168
168
|
femagtools/templates/statorBG.mako,sha256=fh0cVOZVWyLojlGxWJoFz2pvdL6Yxy4xzhY-Joc2xeg,893
|
169
|
+
femagtools/templates/statorKS1.mako,sha256=uqisqazTzopmhjUR8O660yIfsexqxj4ISHaNZIdwTSo,1285
|
169
170
|
femagtools/templates/statorRing.mako,sha256=_X8t9oAD_6SZ_MlLc450SkN4C6pH4dG5LS09D8bv9SE,2071
|
170
171
|
femagtools/templates/statorRotor3.mako,sha256=6ycHlkSnk-TKFdoxiOqjpr6Pk0l634w3_O94vvRP4BI,4357
|
171
172
|
femagtools/templates/stator_msh.mako,sha256=Neze1ielMCk7TrARyhOra91fFQVT8Phsgk2Omt_aMG8,1799
|
172
173
|
femagtools/templates/therm-dynamic.mako,sha256=pEz7jrUpopK1-RqgulNnrkSaCZDjfLelsVo6cBqmpac,3142
|
173
174
|
femagtools/templates/therm_static.mako,sha256=ulevp4AP-kZ1_qdScPMaX9tLqvvP0t9lFflWTXgUxaE,1310
|
174
175
|
femagtools/templates/torq_calc.mako,sha256=PH2IXg9ysi0w8N_8YB0IsE3rRj2VE2AYkGortQxFGfQ,2424
|
175
|
-
femagtools-1.8.
|
176
|
+
femagtools-1.8.19.dist-info/licenses/LICENSE,sha256=NaQe4uvkszQPJmiRPHecfk-Ab9VSRXo8xQLGNVHTeFo,1362
|
176
177
|
tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
177
178
|
tests/test_afpm.py,sha256=ge5CXnVQ7E5gVViTI9hQOC0hHetBci18pY9prbUCAqU,16849
|
178
179
|
tests/test_airgap_induction.py,sha256=cmpy1og59oWEyCO4oF_zDuc1DUwCbdeebNL1ujpZza4,1065
|
@@ -222,8 +223,8 @@ tests/moo/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
222
223
|
tests/moo/test_algorithm.py,sha256=Em8sFm2vzPmuIzRrBBnUQLU_TYuJHSf-kEeozw0XeX4,2563
|
223
224
|
tests/moo/test_population.py,sha256=FvX9LRCxQx0_E2GxHQ5vKwOYFBQiNbT6Lmv5GmNWjTQ,5471
|
224
225
|
tests/moo/test_problem.py,sha256=ALeP4u7g-dFhfwWL8vxivdrrYzVKPjHMCAXzzgyNZbs,467
|
225
|
-
femagtools-1.8.
|
226
|
-
femagtools-1.8.
|
227
|
-
femagtools-1.8.
|
228
|
-
femagtools-1.8.
|
229
|
-
femagtools-1.8.
|
226
|
+
femagtools-1.8.19.dist-info/METADATA,sha256=t50AFbbiCAWPpTQ6fp1FO25ZkCOY1QJMUtN-WX2Lyu0,6221
|
227
|
+
femagtools-1.8.19.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
228
|
+
femagtools-1.8.19.dist-info/entry_points.txt,sha256=jrvOkZPiN44u1sASeu271VRaVIv5V-uRpN0_N5U_R8c,248
|
229
|
+
femagtools-1.8.19.dist-info/top_level.txt,sha256=Ri4YWtU8MZTzNje9IKyXhTakNbsrCynuWdon4Yq94Dc,17
|
230
|
+
femagtools-1.8.19.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|