femagtools 1.8.5__py3-none-any.whl → 1.8.7__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 +16 -9
- femagtools/dxfsl/area.py +3 -0
- femagtools/dxfsl/conv.py +1 -8
- femagtools/dxfsl/converter.py +62 -144
- femagtools/dxfsl/geom.py +49 -0
- femagtools/femag.py +13 -72
- femagtools/fsl.py +6 -3
- femagtools/isa7.py +47 -3
- femagtools/losscoeffs.py +29 -3
- femagtools/machine/afpm.py +82 -21
- femagtools/mcv.py +162 -7
- femagtools/multiproc.py +2 -1
- femagtools/parstudy.py +3 -1
- femagtools/plot/__init__.py +1 -0
- femagtools/plot/bch.py +172 -36
- femagtools/plot/machine.py +100 -0
- femagtools/plot/nc.py +13 -0
- femagtools/poc.py +10 -0
- femagtools/shortcircuit.py +378 -0
- femagtools/templates/psi-torq-rem-rot.mako +127 -0
- femagtools/utils.py +2 -0
- femagtools/zmq.py +22 -4
- {femagtools-1.8.5.dist-info → femagtools-1.8.7.dist-info}/METADATA +1 -1
- {femagtools-1.8.5.dist-info → femagtools-1.8.7.dist-info}/RECORD +30 -27
- tests/test_nc.py +11 -0
- {femagtools-1.8.5.dist-info → femagtools-1.8.7.dist-info}/LICENSE +0 -0
- {femagtools-1.8.5.dist-info → femagtools-1.8.7.dist-info}/WHEEL +0 -0
- {femagtools-1.8.5.dist-info → femagtools-1.8.7.dist-info}/entry_points.txt +0 -0
- {femagtools-1.8.5.dist-info → femagtools-1.8.7.dist-info}/top_level.txt +0 -0
femagtools/__init__.py
CHANGED
femagtools/bch.py
CHANGED
@@ -618,8 +618,8 @@ class Reader:
|
|
618
618
|
|
619
619
|
def __read_peak_winding_currents(self, content):
|
620
620
|
self.scData['peakWindingCurrents'] = [float(x)
|
621
|
-
for x in
|
622
|
-
|
621
|
+
for x in self._numPattern.findall(
|
622
|
+
''.join(content))]
|
623
623
|
|
624
624
|
def __read_general_machine_data(self, content):
|
625
625
|
mcfiles = []
|
@@ -1057,10 +1057,11 @@ class Reader:
|
|
1057
1057
|
e.g. : idList[-450, -350, -250, -150, -50, 0]
|
1058
1058
|
idList[-500, -400, -300, -200, -100, 0, 0]
|
1059
1059
|
'''
|
1060
|
-
|
1061
|
-
if idList[-1] == 0 and len(idList) > 2 and \
|
1062
|
-
diff[-1] == 0:
|
1060
|
+
if list(idList).count(0) > 1: # femag writes duplicate id==0 values
|
1063
1061
|
idList = idList[:-1]
|
1062
|
+
diff = np.floor(np.abs(np.diff(idList)))
|
1063
|
+
if n := np.trim_zeros(np.diff(diff)).size:
|
1064
|
+
idList = idList[:-n]
|
1064
1065
|
return idList
|
1065
1066
|
|
1066
1067
|
def __read_psidq(self, content):
|
@@ -1085,8 +1086,7 @@ class Reader:
|
|
1085
1086
|
ncols = ncols-1
|
1086
1087
|
|
1087
1088
|
id = np.reshape(m[0], (-1, ncols)).T[0]
|
1088
|
-
|
1089
|
-
id = self.__removeTrailingZero(id)
|
1089
|
+
id = self.__removeTrailingZero(id)
|
1090
1090
|
nrows = len(id)
|
1091
1091
|
if nrows > 1 and id[nrows-1] < id[nrows-2]:
|
1092
1092
|
nrows = nrows-1
|
@@ -1121,8 +1121,7 @@ class Reader:
|
|
1121
1121
|
ncols = ncols-1
|
1122
1122
|
|
1123
1123
|
id = np.reshape(m[0], (-1, ncols)).T[0]
|
1124
|
-
|
1125
|
-
id = self.__removeTrailingZero(id)
|
1124
|
+
id = self.__removeTrailingZero(id)
|
1126
1125
|
nrows = len(id)
|
1127
1126
|
if nrows > 1 and id[nrows-1] < id[nrows-2]:
|
1128
1127
|
nrows = nrows-1
|
@@ -1610,6 +1609,11 @@ class Reader:
|
|
1610
1609
|
losses['staza'] = floatnan(rec[0])
|
1611
1610
|
losses['stajo'] = floatnan(rec[1])
|
1612
1611
|
losses['total'] += losses['staza']+losses['stajo']
|
1612
|
+
|
1613
|
+
elif content[i+1].split() == ['Iron', '----']:
|
1614
|
+
losses['rotfe'] = sum([floatnan(x) for x in rec])
|
1615
|
+
losses['total'] += losses['rotfe']
|
1616
|
+
|
1613
1617
|
else:
|
1614
1618
|
losses['rotfe'] = floatnan(rec[1])
|
1615
1619
|
losses['total'] += losses['rotfe']
|
@@ -1771,6 +1775,9 @@ class Reader:
|
|
1771
1775
|
def __getattr__(self, k):
|
1772
1776
|
return self.__dict__[k]
|
1773
1777
|
|
1778
|
+
def asdict(self):
|
1779
|
+
return {k[0]: k[1] for k in self.items()}
|
1780
|
+
|
1774
1781
|
def items(self):
|
1775
1782
|
return [(k, self.get(k)) for k in ('version',
|
1776
1783
|
'type',
|
femagtools/dxfsl/area.py
CHANGED
@@ -435,6 +435,9 @@ class Area(object):
|
|
435
435
|
self.type == TYPE_WINDINGS or \
|
436
436
|
self.type == TYPE_FD_WINDINGS
|
437
437
|
|
438
|
+
def is_field_winding(self):
|
439
|
+
return self.type == TYPE_FD_WINDINGS
|
440
|
+
|
438
441
|
def is_magnet(self):
|
439
442
|
return self.type == TYPE_MAGNET_AIRGAP or self.type == TYPE_MAGNET_RECT
|
440
443
|
|
femagtools/dxfsl/conv.py
CHANGED
@@ -180,12 +180,6 @@ def main():
|
|
180
180
|
help='create full model (fsl only)',
|
181
181
|
dest='full_model',
|
182
182
|
action="store_true")
|
183
|
-
argparser.add_argument('--no_processing',
|
184
|
-
help=(argparse.SUPPRESS if not super_help else
|
185
|
-
"omit multiprocessing"),
|
186
|
-
dest='no_processing',
|
187
|
-
action="store_true",
|
188
|
-
default=False)
|
189
183
|
|
190
184
|
args = argparser.parse_args()
|
191
185
|
|
@@ -282,8 +276,7 @@ def main():
|
|
282
276
|
write_id=args.write_id,
|
283
277
|
debug_mode=args.debugger,
|
284
278
|
full_model=args.full_model,
|
285
|
-
write_journal=args.journal
|
286
|
-
no_processing=args.no_processing)
|
279
|
+
write_journal=args.journal)
|
287
280
|
keys = ('tot_num_slot', 'num_sl_gen', 'num_poles', 'nodedist',
|
288
281
|
'dy1', 'da1', 'da2', 'dy2', 'agndst', 'name')
|
289
282
|
logger.info("%s", {k: res[k] for k in keys if k in res})
|
femagtools/dxfsl/converter.py
CHANGED
@@ -10,7 +10,7 @@ from femagtools.dxfsl.shape import Shape
|
|
10
10
|
from femagtools.dxfsl.fslrenderer import FslRenderer, agndst
|
11
11
|
from femagtools.dxfsl.plotrenderer import PlotRenderer
|
12
12
|
from femagtools.dxfsl.concat import Concatenation
|
13
|
-
from femagtools.dxfsl.functions import Timer,
|
13
|
+
from femagtools.dxfsl.functions import Timer, middle_angle
|
14
14
|
from femagtools.dxfsl.journal import Journal, getJournal
|
15
15
|
from femagtools.dxfsl.area import TYPE_WINDINGS
|
16
16
|
from femagtools.dxfsl.areabuilder import disable_logging, enable_logging
|
@@ -18,7 +18,6 @@ import logging
|
|
18
18
|
import logging.config
|
19
19
|
import numpy as np
|
20
20
|
import sys
|
21
|
-
import multiprocessing
|
22
21
|
|
23
22
|
logger = logging.getLogger(__name__)
|
24
23
|
|
@@ -43,117 +42,6 @@ def plot_geom(doit, plt, geom, title="Plot", areas=True):
|
|
43
42
|
fill_areas=areas)
|
44
43
|
|
45
44
|
|
46
|
-
class SymSearchProcess(SimpleProcess):
|
47
|
-
def __init__(self,
|
48
|
-
name=None,
|
49
|
-
queue=None,
|
50
|
-
machine=None,
|
51
|
-
plt=None, # plotter
|
52
|
-
kind="",
|
53
|
-
mindist=0.01,
|
54
|
-
symtol=0.0,
|
55
|
-
sympart=0,
|
56
|
-
is_inner=False,
|
57
|
-
is_outer=False,
|
58
|
-
show_plots=True,
|
59
|
-
debug_mode=False,
|
60
|
-
rows=1,
|
61
|
-
cols=1,
|
62
|
-
num=1,
|
63
|
-
no_processing=False):
|
64
|
-
SimpleProcess.__init__(self,
|
65
|
-
name=name,
|
66
|
-
no_processing=no_processing)
|
67
|
-
self.queue = queue
|
68
|
-
self.mach_in = machine
|
69
|
-
self.mach_out = None
|
70
|
-
self.plt = plt
|
71
|
-
self.kind = kind
|
72
|
-
self.mindist = mindist
|
73
|
-
self.symtol = symtol
|
74
|
-
self.sympart = sympart
|
75
|
-
self.is_inner = is_inner
|
76
|
-
self.is_outer = is_outer
|
77
|
-
self.show_plots = show_plots
|
78
|
-
self.debug_mode = debug_mode
|
79
|
-
self.rows = rows
|
80
|
-
self.cols = cols
|
81
|
-
self.num = num
|
82
|
-
pass
|
83
|
-
|
84
|
-
def run(self):
|
85
|
-
if not self.without_processing():
|
86
|
-
logger.info("Process is running")
|
87
|
-
self.plt = None
|
88
|
-
self.show_plots = False
|
89
|
-
else:
|
90
|
-
logger.info("without multiprocessing")
|
91
|
-
|
92
|
-
try:
|
93
|
-
self.mach_out = symmetry_search(
|
94
|
-
self.mach_in,
|
95
|
-
plt=self.plt,
|
96
|
-
kind=self.kind,
|
97
|
-
mindist=self.mindist,
|
98
|
-
symtol=self.symtol,
|
99
|
-
sympart=self.sympart,
|
100
|
-
is_inner=self.is_inner,
|
101
|
-
is_outer=self.is_outer,
|
102
|
-
show_plots=self.show_plots,
|
103
|
-
debug_mode=self.debug_mode,
|
104
|
-
rows=self.rows,
|
105
|
-
cols=self.cols,
|
106
|
-
num=self.num)
|
107
|
-
except Exception as e:
|
108
|
-
logger.warning("Exception in symmetry_search: %s", e)
|
109
|
-
if not self.mach_out:
|
110
|
-
logger.error("NO MACHINE AFTER PROCESS")
|
111
|
-
self.queue.put(self.mach_out)
|
112
|
-
if not self.without_processing():
|
113
|
-
logger.info("Process is finished")
|
114
|
-
|
115
|
-
|
116
|
-
class BuildInnerProcess(SimpleProcess):
|
117
|
-
def __init__(self,
|
118
|
-
name=None,
|
119
|
-
queue=None,
|
120
|
-
machine=None,
|
121
|
-
mindist=0.01,
|
122
|
-
plt=None, # plotter
|
123
|
-
EESM=False,
|
124
|
-
no_processing=False):
|
125
|
-
SimpleProcess.__init__(self,
|
126
|
-
name=name,
|
127
|
-
no_processing=no_processing)
|
128
|
-
self.queue = queue
|
129
|
-
self.mach_in = machine
|
130
|
-
self.mach_out = None
|
131
|
-
self.plt = plt
|
132
|
-
self.mindist = mindist
|
133
|
-
self.EESM = EESM
|
134
|
-
pass
|
135
|
-
|
136
|
-
def run(self):
|
137
|
-
if not self.without_processing():
|
138
|
-
logger.info("Process is running")
|
139
|
-
self.plt = None
|
140
|
-
else:
|
141
|
-
logger.info("without multiprocessing")
|
142
|
-
|
143
|
-
try:
|
144
|
-
self.mach_out = build_inner_machine(
|
145
|
-
self.mach_in,
|
146
|
-
mindist=self.mindist,
|
147
|
-
plt=self.plt,
|
148
|
-
EESM=self.EESM)
|
149
|
-
except Exception as e:
|
150
|
-
logger.warning("Exception in symmetry_search: %s", e)
|
151
|
-
|
152
|
-
self.queue.put(self.mach_out)
|
153
|
-
if not self.without_processing():
|
154
|
-
logger.info("Process is finished")
|
155
|
-
|
156
|
-
|
157
45
|
def symmetry_search(machine,
|
158
46
|
plt=None, # plotter
|
159
47
|
kind="single",
|
@@ -348,6 +236,7 @@ def build_machine_rotor(machine, inner, mindist, plt, EESM=False, single=False):
|
|
348
236
|
title="Final Rotor")
|
349
237
|
|
350
238
|
t = timer.stop("-- rotor created in %0.4f seconds --")
|
239
|
+
journal.put('time_rotor_created', t)
|
351
240
|
|
352
241
|
logger.debug("End of build_machine_rotor")
|
353
242
|
return machine_temp
|
@@ -420,6 +309,7 @@ def build_machine_stator(machine, inner, mindist, plt, EESM=False, single=False)
|
|
420
309
|
title="Final Stator")
|
421
310
|
|
422
311
|
t = timer.stop("-- stator created in %0.4f seconds --")
|
312
|
+
journal.put('time_stator_created', t)
|
423
313
|
|
424
314
|
logger.debug("End of build_machine_stator")
|
425
315
|
return machine_temp
|
@@ -504,8 +394,7 @@ def convert(dxfile,
|
|
504
394
|
write_id=False,
|
505
395
|
full_model=False,
|
506
396
|
debug_mode=False,
|
507
|
-
write_journal=False
|
508
|
-
no_processing=False):
|
397
|
+
write_journal=False):
|
509
398
|
global journal
|
510
399
|
layers = ()
|
511
400
|
conv = {}
|
@@ -724,23 +613,19 @@ def convert(dxfile,
|
|
724
613
|
machine_outer.set_outer()
|
725
614
|
|
726
615
|
start_timer.stop("-- first part in %0.4f seconds --", info=True)
|
616
|
+
|
727
617
|
process_timer = Timer(start_it=True)
|
728
618
|
# inner part
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
738
|
-
|
739
|
-
rows=3, # rows
|
740
|
-
cols=2, # columns
|
741
|
-
num=3, # start num
|
742
|
-
no_processing=no_processing)
|
743
|
-
inner_proc.start_task()
|
619
|
+
machine_inner = symmetry_search(machine=machine_inner,
|
620
|
+
plt=p, # plot
|
621
|
+
kind=inner_name,
|
622
|
+
is_inner=True,
|
623
|
+
mindist=mindist,
|
624
|
+
symtol=symtol,
|
625
|
+
show_plots=show_plots,
|
626
|
+
rows=3, # rows
|
627
|
+
cols=2, # columns
|
628
|
+
num=3) # start num
|
744
629
|
|
745
630
|
# outer part
|
746
631
|
machine_outer = symmetry_search(machine_outer,
|
@@ -754,29 +639,20 @@ def convert(dxfile,
|
|
754
639
|
cols=2, # columns
|
755
640
|
num=4) # start num
|
756
641
|
|
757
|
-
machine_inner = inner_queue.get()
|
758
|
-
inner_proc.wait()
|
759
642
|
process_timer.stop("-- symmetry search in %0.4f seconds --", info=True)
|
760
643
|
|
761
644
|
machine_inner.sync_with_counterpart(machine_outer)
|
762
645
|
|
763
646
|
final_timer = Timer(start_it=True)
|
764
|
-
|
765
|
-
|
766
|
-
|
767
|
-
|
768
|
-
mindist=mindist,
|
769
|
-
plt=p,
|
770
|
-
EESM=EESM,
|
771
|
-
no_processing=no_processing)
|
772
|
-
inner_proc.start_task()
|
647
|
+
machine_inner = build_inner_machine(machine_inner,
|
648
|
+
mindist=mindist,
|
649
|
+
plt=p,
|
650
|
+
EESM=EESM)
|
773
651
|
|
774
652
|
machine_outer = build_outer_machine(machine_outer,
|
775
653
|
mindist,
|
776
654
|
p,
|
777
655
|
EESM=EESM)
|
778
|
-
machine_inner = inner_queue.get()
|
779
|
-
inner_proc.wait()
|
780
656
|
final_timer.stop("-- final part in %0.4f seconds --", info=True)
|
781
657
|
|
782
658
|
machine_inner.sync_with_counterpart(machine_outer)
|
@@ -958,7 +834,7 @@ def convert(dxfile,
|
|
958
834
|
r_out = 0.0
|
959
835
|
r_in = 0.0
|
960
836
|
if machine.cut_is_possible(r_in, r_out):
|
961
|
-
logger.
|
837
|
+
logger.debug("make a cut")
|
962
838
|
machine = machine.cut(r_in, r_out)
|
963
839
|
|
964
840
|
if part:
|
@@ -1080,6 +956,37 @@ def convert(dxfile,
|
|
1080
956
|
return conv
|
1081
957
|
|
1082
958
|
|
959
|
+
def _create_rotor_parameters(machine):
|
960
|
+
rotor = {
|
961
|
+
'min_radius': machine.geom.min_radius,
|
962
|
+
'max_radius': machine.geom.max_radius,
|
963
|
+
'mags': machine.geom.magnets_minmax_list(),
|
964
|
+
'fd_wnds': machine.geom.fd_windings_minmax_list()
|
965
|
+
}
|
966
|
+
shaft_min, shaft_max = machine.geom.shaft_minmax()
|
967
|
+
if shaft_max > 0.0:
|
968
|
+
rotor['shaft_min'] = shaft_min
|
969
|
+
rotor['shaft_max'] = shaft_max
|
970
|
+
if shaft_max > rotor['min_radius']:
|
971
|
+
rotor['min_radius'] = shaft_max
|
972
|
+
return rotor
|
973
|
+
|
974
|
+
|
975
|
+
def _create_stator_parameters(machine):
|
976
|
+
stator = {
|
977
|
+
'min_radius': machine.geom.min_radius,
|
978
|
+
'max_radius': machine.geom.max_radius,
|
979
|
+
'wnds': machine.geom.windings_minmax_list()
|
980
|
+
}
|
981
|
+
shaft_min, shaft_max = machine.geom.shaft_minmax()
|
982
|
+
if shaft_max > 0.0:
|
983
|
+
stator['shaft_min'] = shaft_min
|
984
|
+
stator['shaft_max'] = shaft_max
|
985
|
+
if shaft_max > stator['min_radius']:
|
986
|
+
stator['min_radius'] = shaft_max
|
987
|
+
return stator
|
988
|
+
|
989
|
+
|
1083
990
|
def create_femag_parameters(m_inner, m_outer, nodedist=1):
|
1084
991
|
if not (m_inner and m_outer):
|
1085
992
|
logger.warning("inner %s outer %s", m_inner, m_outer)
|
@@ -1122,6 +1029,13 @@ def create_femag_parameters(m_inner, m_outer, nodedist=1):
|
|
1122
1029
|
params['alfa_slot'] = alfa_slot
|
1123
1030
|
params['alfa_pole'] = alfa_pole
|
1124
1031
|
|
1032
|
+
if m_inner.geom.is_rotor():
|
1033
|
+
params['rotor'] = _create_rotor_parameters(m_inner)
|
1034
|
+
params['stator'] = _create_stator_parameters(m_outer)
|
1035
|
+
else:
|
1036
|
+
params['rotor'] = _create_rotor_parameters(m_outer)
|
1037
|
+
params['stator'] = _create_stator_parameters(m_inner)
|
1038
|
+
|
1125
1039
|
if num_slots == 0 or num_poles == 0:
|
1126
1040
|
if num_slots == 0:
|
1127
1041
|
logger.warning("No slots found")
|
@@ -1149,6 +1063,8 @@ def create_femag_parameters_stator(motor, position):
|
|
1149
1063
|
params['dy1'] = 2*motor.geom.max_radius
|
1150
1064
|
params['da1'] = 2*motor.geom.min_radius
|
1151
1065
|
params['slot_area'] = motor.slot_area()
|
1066
|
+
params['stator'] = _create_stator_parameters(motor)
|
1067
|
+
params['machine'] = motor
|
1152
1068
|
return params
|
1153
1069
|
|
1154
1070
|
|
@@ -1163,4 +1079,6 @@ def create_femag_parameters_rotor(motor, position):
|
|
1163
1079
|
params['dy1'] = 2*motor.geom.max_radius
|
1164
1080
|
params['da1'] = 2*motor.geom.min_radius
|
1165
1081
|
params['slot_area'] = motor.slot_area()
|
1082
|
+
params['rotor'] = _create_rotor_parameters(motor)
|
1083
|
+
params['machine'] = motor
|
1166
1084
|
return params
|
femagtools/dxfsl/geom.py
CHANGED
@@ -4528,6 +4528,55 @@ class Geometry(object):
|
|
4528
4528
|
add_element(e)
|
4529
4529
|
self.area_list += area_list
|
4530
4530
|
|
4531
|
+
def areas_minmax_list(self, area_list):
|
4532
|
+
if not area_list:
|
4533
|
+
return []
|
4534
|
+
|
4535
|
+
dist_list = []
|
4536
|
+
for n, a in enumerate(area_list):
|
4537
|
+
dist_list.append((a.min_dist, a.max_dist, n))
|
4538
|
+
dist_list.sort()
|
4539
|
+
|
4540
|
+
minmax_list = []
|
4541
|
+
d1_this, d2_this, n = dist_list [0]
|
4542
|
+
for d1_next, d2_next, n in dist_list[1:]:
|
4543
|
+
if d1_next > d2_this:
|
4544
|
+
minmax_list.append((d1_this, d2_this))
|
4545
|
+
d1_this = d1_next
|
4546
|
+
d2_this = d2_next
|
4547
|
+
else:
|
4548
|
+
d2_this = max(d2_this, d2_next)
|
4549
|
+
minmax_list.append((d1_this, d2_this))
|
4550
|
+
return minmax_list
|
4551
|
+
|
4552
|
+
def magnets_minmax_list(self):
|
4553
|
+
magnets = [a for a in self.list_of_areas()
|
4554
|
+
if a.is_magnet()]
|
4555
|
+
return self.areas_minmax_list(magnets)
|
4556
|
+
|
4557
|
+
def windings_minmax_list(self):
|
4558
|
+
windings = [a for a in self.list_of_areas()
|
4559
|
+
if a.is_winding()]
|
4560
|
+
return self.areas_minmax_list(windings)
|
4561
|
+
|
4562
|
+
def fd_windings_minmax_list(self):
|
4563
|
+
windings = [a for a in self.list_of_areas()
|
4564
|
+
if a.is_field_winding()]
|
4565
|
+
return self.areas_minmax_list(windings)
|
4566
|
+
|
4567
|
+
def shaft_minmax(self):
|
4568
|
+
shafts = [a for a in self.list_of_areas()
|
4569
|
+
if a.is_shaft()]
|
4570
|
+
if not shafts:
|
4571
|
+
return (0.0, 0.0)
|
4572
|
+
|
4573
|
+
dmin = shafts[0].min_dist
|
4574
|
+
dmax = shafts[0].max_dist
|
4575
|
+
for s in shafts[1:]:
|
4576
|
+
dmin = min(dmin, s.min_dist)
|
4577
|
+
dmax = max(dmax, s.max_dist)
|
4578
|
+
return (dmin, dmax)
|
4579
|
+
|
4531
4580
|
def check_airgap_connecting_nodes(self, geom, startangle, endangle):
|
4532
4581
|
logger.info("check_airgap_connecting_nodes")
|
4533
4582
|
|
femagtools/femag.py
CHANGED
@@ -61,43 +61,6 @@ def handle_process_output(filedes, outfile, log):
|
|
61
61
|
pass
|
62
62
|
|
63
63
|
|
64
|
-
def get_shortCircuit_parameters(bch, nload):
|
65
|
-
try:
|
66
|
-
if nload < 0:
|
67
|
-
nload = 0
|
68
|
-
if nload > 2:
|
69
|
-
nload = 2
|
70
|
-
if nload > 0:
|
71
|
-
dqld = bch.dqPar['ld']
|
72
|
-
dqlq = bch.dqPar['lq']
|
73
|
-
dqpsim = bch.dqPar['psim']
|
74
|
-
if len(dqld) <= nload or len(dqlq) <= nload or len(dqpsim) <= nload:
|
75
|
-
ld = dqld[-1]/bch.armatureLength
|
76
|
-
lq = dqlq[-1]/bch.armatureLength
|
77
|
-
psim = dqpsim[-1]/bch.armatureLength
|
78
|
-
else:
|
79
|
-
ld = dqld[nload-1]/bch.armatureLength
|
80
|
-
lq = dqlq[nload-1]/bch.armatureLength
|
81
|
-
psim = dqpsim[nload-1]/bch.armatureLength
|
82
|
-
else:
|
83
|
-
ld = bch.machine['ld']/bch.armatureLength
|
84
|
-
lq = bch.machine['lq']/bch.armatureLength
|
85
|
-
psim = bch.machine['psim']/bch.armatureLength
|
86
|
-
return dict(
|
87
|
-
r1=bch.machine['r1'],
|
88
|
-
ld=ld,
|
89
|
-
lq=lq,
|
90
|
-
psim=psim,
|
91
|
-
num_pol_pair=bch.machine['p'],
|
92
|
-
fc_radius=bch.machine['fc_radius'],
|
93
|
-
lfe=bch.armatureLength/1e3,
|
94
|
-
pocfilename=bch.machine['pocfile'],
|
95
|
-
num_par_wdgs=bch.machine.get('num_par_wdgs', 0),
|
96
|
-
calculationMode='shortcircuit')
|
97
|
-
except (KeyError, AttributeError, IndexError):
|
98
|
-
raise FemagError("missing pm/Rel-Sim results")
|
99
|
-
|
100
|
-
|
101
64
|
def set_magnet_properties(model, simulation, magnets):
|
102
65
|
"""set temperature adapted magnet properties"""
|
103
66
|
if not hasattr(model, 'magnet'):
|
@@ -449,7 +412,7 @@ class BaseFemag(object):
|
|
449
412
|
|
450
413
|
return list(pathlib.Path(self.workdir).glob('*.PROT'))[0].stem
|
451
414
|
|
452
|
-
def readResult(self, simulation, bch=None):
|
415
|
+
def readResult(self, machine, simulation, bch=None):
|
453
416
|
if simulation:
|
454
417
|
if simulation['calculationMode'] == "fieldcalc":
|
455
418
|
nc = self.read_nc()
|
@@ -495,38 +458,11 @@ class BaseFemag(object):
|
|
495
458
|
if simulation['calculationMode'] == 'pm_sym_fast' or \
|
496
459
|
simulation['calculationMode'] == 'torq_calc':
|
497
460
|
if simulation.get('shortCircuit', False):
|
498
|
-
|
499
|
-
simulation.update(
|
500
|
-
get_shortCircuit_parameters(bch,
|
501
|
-
simulation.get('initial', 2)))
|
502
|
-
|
503
|
-
builder = femagtools.fsl.Builder(self.templatedirs)
|
461
|
+
from .shortcircuit import shortcircuit
|
504
462
|
set_magnet_properties(self.model, simulation, self.magnets)
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
with open(os.path.join(self.workdir, fslfile), 'w') as f:
|
509
|
-
f.write('\n'.join(fslcmds))
|
510
|
-
self.run(fslfile) #, options?
|
511
|
-
bchfile = self.get_bch_file(self.modelname)
|
512
|
-
if bchfile:
|
513
|
-
bchsc = femagtools.bch.Reader()
|
514
|
-
logger.info("Read BCH {}".format(bchfile))
|
515
|
-
with io.open(bchfile, encoding='latin1',
|
516
|
-
errors='ignore') as f:
|
517
|
-
bchsc.read(f)
|
518
|
-
bch.scData = bchsc.scData
|
519
|
-
for w in bch.flux:
|
520
|
-
try:
|
521
|
-
bch.flux[w] += bchsc.flux[w]
|
522
|
-
bch.flux_fft[w] += bchsc.flux_fft[w]
|
523
|
-
except (KeyError, IndexError):
|
524
|
-
logging.debug(
|
525
|
-
"No additional flux data in sc simulation")
|
526
|
-
break
|
527
|
-
|
528
|
-
bch.torque += bchsc.torque
|
529
|
-
bch.demag += bchsc.demag
|
463
|
+
bch.scData = shortcircuit(self, machine, bch, simulation)
|
464
|
+
#bch.torque += bchsc.torque
|
465
|
+
#bch.demag += bchsc.demag
|
530
466
|
|
531
467
|
if 'airgap_induc' in simulation:
|
532
468
|
try:
|
@@ -699,8 +635,9 @@ class Femag(BaseFemag):
|
|
699
635
|
setattr(self, "dy2", machine['stator']['dy2'])
|
700
636
|
except:
|
701
637
|
pass
|
638
|
+
|
702
639
|
if simulation:
|
703
|
-
return self.readResult(simulation)
|
640
|
+
return self.readResult(machine, simulation)
|
704
641
|
|
705
642
|
return {'status': 'ok', 'message': self.modelname,
|
706
643
|
'model': self.model.props()}
|
@@ -801,9 +738,12 @@ class ZmqFemag(BaseFemag):
|
|
801
738
|
def subscribe(self, notify):
|
802
739
|
"""attaches a notify function"""
|
803
740
|
logger.info("Subscribe on '%s' port %d", self.femaghost, self.port+1)
|
741
|
+
femagtools.zmq.SubscriberTask.clear()
|
804
742
|
if self.subscriber is None:
|
743
|
+
# progress/xyplot at a configured timestep published
|
744
|
+
header = [b'progress', b'xyplot', b'license']
|
805
745
|
self.subscriber = femagtools.zmq.SubscriberTask(
|
806
|
-
port=self.port+1, host=self.femaghost, notify=notify)
|
746
|
+
port=self.port+1, host=self.femaghost, notify=notify, header=header)
|
807
747
|
self.subscriber.start()
|
808
748
|
else:
|
809
749
|
# reattach?
|
@@ -1087,7 +1027,7 @@ class ZmqFemag(BaseFemag):
|
|
1087
1027
|
response = self.send_request(
|
1088
1028
|
['CONTROL', f'getfile = {filename}'], timeout=1000)
|
1089
1029
|
return [response[0].decode('latin1'),
|
1090
|
-
response[1] if len(response) else b'']
|
1030
|
+
response[1] if len(response) > 1 else b'']
|
1091
1031
|
|
1092
1032
|
def exportsvg(self, fslcmds, timeout=10000):
|
1093
1033
|
"""get svg format from fsl commands (if any graphic created)
|
@@ -1156,6 +1096,7 @@ class ZmqFemag(BaseFemag):
|
|
1156
1096
|
logger.info("Interrupt %s", self.femaghost)
|
1157
1097
|
ctrl.send_string('interrupt')
|
1158
1098
|
ctrl.close()
|
1099
|
+
femagtools.zmq.SubscriberTask.clear()
|
1159
1100
|
|
1160
1101
|
def copy_winding_file(self, name, wdg):
|
1161
1102
|
wdg.write(name, self.workdir)
|
femagtools/fsl.py
CHANGED
@@ -227,7 +227,7 @@ class Builder:
|
|
227
227
|
# obsolete
|
228
228
|
th_props = [' ']
|
229
229
|
try:
|
230
|
-
logger.
|
230
|
+
logger.debug(model.magnet)
|
231
231
|
th_props = [f'rotor_density = {model["magnet"]["density"]}',
|
232
232
|
f'rotor_thcond = {model["magnet"]["thcond"]}',
|
233
233
|
f'rotor_thcap = {model["magnet"]["thcap"]}'
|
@@ -750,8 +750,11 @@ class Builder:
|
|
750
750
|
sim['eccentricity'])
|
751
751
|
|
752
752
|
if sim.get('calculationMode') == 'pm_sym_f_cur':
|
753
|
-
if 'nload_ex_cur'
|
754
|
-
sim
|
753
|
+
if sim.get('nload_ex_cur', ''): # convert obsolete key
|
754
|
+
if isinstance(sim, dict):
|
755
|
+
sim['noload_ex_cur'] = sim.pop('nload_ex_cur')
|
756
|
+
else:
|
757
|
+
sim.noload_ex_cur = sim.get('nload_ex_cur')
|
755
758
|
felosses = custom_fefunc + self.create_fe_losses(sim)
|
756
759
|
fslcalc = (displ_stator_rotor
|
757
760
|
+ self.__render(sim, sim.get('calculationMode'))
|