femagtools 1.8.5__py3-none-any.whl → 1.8.6__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 +5 -2
- 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 +5 -2
- femagtools/machine/afpm.py +73 -21
- femagtools/multiproc.py +2 -1
- femagtools/plot/__init__.py +1 -0
- femagtools/plot/bch.py +57 -3
- femagtools/plot/machine.py +100 -0
- femagtools/poc.py +10 -0
- femagtools/utils.py +2 -0
- femagtools/zmq.py +22 -4
- {femagtools-1.8.5.dist-info → femagtools-1.8.6.dist-info}/METADATA +1 -1
- {femagtools-1.8.5.dist-info → femagtools-1.8.6.dist-info}/RECORD +21 -20
- {femagtools-1.8.5.dist-info → femagtools-1.8.6.dist-info}/LICENSE +0 -0
- {femagtools-1.8.5.dist-info → femagtools-1.8.6.dist-info}/WHEEL +0 -0
- {femagtools-1.8.5.dist-info → femagtools-1.8.6.dist-info}/entry_points.txt +0 -0
- {femagtools-1.8.5.dist-info → femagtools-1.8.6.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 = []
|
@@ -1771,6 +1771,9 @@ class Reader:
|
|
1771
1771
|
def __getattr__(self, k):
|
1772
1772
|
return self.__dict__[k]
|
1773
1773
|
|
1774
|
+
def asdict(self):
|
1775
|
+
return {k[0]: k[1] for k in self.items()}
|
1776
|
+
|
1774
1777
|
def items(self):
|
1775
1778
|
return [(k, self.get(k)) for k in ('version',
|
1776
1779
|
'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
@@ -802,8 +802,10 @@ class ZmqFemag(BaseFemag):
|
|
802
802
|
"""attaches a notify function"""
|
803
803
|
logger.info("Subscribe on '%s' port %d", self.femaghost, self.port+1)
|
804
804
|
if self.subscriber is None:
|
805
|
+
# progress/xyplot at a configured timestep published
|
806
|
+
header = [b'progress', b'xyplot', b'license']
|
805
807
|
self.subscriber = femagtools.zmq.SubscriberTask(
|
806
|
-
port=self.port+1, host=self.femaghost, notify=notify)
|
808
|
+
port=self.port+1, host=self.femaghost, notify=notify, header=header)
|
807
809
|
self.subscriber.start()
|
808
810
|
else:
|
809
811
|
# reattach?
|
@@ -1087,7 +1089,7 @@ class ZmqFemag(BaseFemag):
|
|
1087
1089
|
response = self.send_request(
|
1088
1090
|
['CONTROL', f'getfile = {filename}'], timeout=1000)
|
1089
1091
|
return [response[0].decode('latin1'),
|
1090
|
-
response[1] if len(response) else b'']
|
1092
|
+
response[1] if len(response) > 1 else b'']
|
1091
1093
|
|
1092
1094
|
def exportsvg(self, fslcmds, timeout=10000):
|
1093
1095
|
"""get svg format from fsl commands (if any graphic created)
|
@@ -1156,6 +1158,7 @@ class ZmqFemag(BaseFemag):
|
|
1156
1158
|
logger.info("Interrupt %s", self.femaghost)
|
1157
1159
|
ctrl.send_string('interrupt')
|
1158
1160
|
ctrl.close()
|
1161
|
+
femagtools.zmq.SubscriberTask.clear()
|
1159
1162
|
|
1160
1163
|
def copy_winding_file(self, name, wdg):
|
1161
1164
|
wdg.write(name, self.workdir)
|
femagtools/machine/afpm.py
CHANGED
@@ -15,6 +15,7 @@ from scipy.interpolate import make_interp_spline, RegularGridInterpolator, RectB
|
|
15
15
|
from scipy.integrate import quad
|
16
16
|
import copy
|
17
17
|
from matplotlib.colors import to_rgb
|
18
|
+
from multiprocessing import Pool
|
18
19
|
|
19
20
|
logger = logging.getLogger(__name__)
|
20
21
|
|
@@ -54,7 +55,8 @@ def _integrate(radius, pos, val):
|
|
54
55
|
interp = RegularGridInterpolator((radius, pos), val)
|
55
56
|
def func(x, y):
|
56
57
|
return interp((x, y))
|
57
|
-
return [quad(func, radius[0], radius[-1],
|
58
|
+
return [quad(func, radius[0], radius[-1],
|
59
|
+
args=(p,), limit=200)[0]
|
58
60
|
for p in pos]
|
59
61
|
|
60
62
|
|
@@ -62,7 +64,7 @@ def _integrate1d(radius, val):
|
|
62
64
|
interp = make_interp_spline(radius, val, k=1)
|
63
65
|
def func(x):
|
64
66
|
return interp((x))
|
65
|
-
return quad(func, radius[0], radius[-1])[0]
|
67
|
+
return quad(func, radius[0], radius[-1], limit=100)[0]
|
66
68
|
|
67
69
|
def ld_interpol(i1, beta, v):
|
68
70
|
'''interpolate Ld at beta angle 0°, -180°'''
|
@@ -152,7 +154,17 @@ def parident(workdir, engine, temp, machine,
|
|
152
154
|
machine[wdgk].get('num_par_wdgs', 1))
|
153
155
|
|
154
156
|
p = machine['poles']
|
155
|
-
|
157
|
+
if np.isscalar(machine['magnet']['afm_rotor']['rel_magn_width']):
|
158
|
+
num_slices = kwargs.get('num_slices', 3)
|
159
|
+
rmagw = num_slices*[machine['magnet']['afm_rotor']['rel_magn_width']]
|
160
|
+
else:
|
161
|
+
rmagw = machine['magnet']['afm_rotor']['rel_magn_width']
|
162
|
+
if len(rmagw) == 1:
|
163
|
+
num_slices = kwargs.get('num_slices', 3)
|
164
|
+
rmagw = num_slices*list(rmagw)
|
165
|
+
else:
|
166
|
+
num_slices = len(rmagw)
|
167
|
+
|
156
168
|
lfe = get_arm_lengths(machine['outer_diam'],
|
157
169
|
machine['inner_diam'],
|
158
170
|
num_slices)
|
@@ -172,6 +184,8 @@ def parident(workdir, engine, temp, machine,
|
|
172
184
|
"decision_vars": [
|
173
185
|
{"values": pole_width,
|
174
186
|
"name": "pole_width"},
|
187
|
+
{"values": rmagw,
|
188
|
+
"name": "magnet.afm_rotor.rel_magn_width"},
|
175
189
|
{"values": lfe,
|
176
190
|
"name": "lfe"},
|
177
191
|
{"values": linspeed, "name": "speed"}
|
@@ -216,9 +230,11 @@ def parident(workdir, engine, temp, machine,
|
|
216
230
|
else:
|
217
231
|
nlresults = {"x": [], "f": []}
|
218
232
|
i = 0
|
219
|
-
|
233
|
+
|
234
|
+
for pw, le, sp, rmw in zip(pole_width, lfe, linspeed, rmagw):
|
220
235
|
nlmachine = {k: machine[k] for k in machine}
|
221
236
|
nlmachine['pole_width'] = pw
|
237
|
+
nlmachine['magnet']['afm_rotor']['rel_magn_width'] = rmw
|
222
238
|
nlmachine['lfe'] = le
|
223
239
|
nlcalc.update({"speed": sp})
|
224
240
|
nlsubdir = f'{workdir}/{i}'
|
@@ -237,10 +253,11 @@ def parident(workdir, engine, temp, machine,
|
|
237
253
|
current_angles = nlresults['f'][0]['current_angles']
|
238
254
|
results = []
|
239
255
|
i = 0
|
240
|
-
for l, pw in zip(lfe, pole_width):
|
256
|
+
for l, pw, rmw in zip(lfe, pole_width, rmagw):
|
241
257
|
mpart = {k: machine[k] for k in machine if k != 'afm_rotor'}
|
242
258
|
mpart['pole_width'] = pw
|
243
259
|
mpart['lfe'] = l
|
260
|
+
mpart['magnet']['afm_rotor']['rel_magn_width'] = rmw
|
244
261
|
subdir = f"{workdir}/{i}"
|
245
262
|
|
246
263
|
simulation = dict(
|
@@ -296,12 +313,23 @@ def parident(workdir, engine, temp, machine,
|
|
296
313
|
i += 1
|
297
314
|
|
298
315
|
postp = []
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
316
|
+
if kwargs.get('use_multiprocessing', True):
|
317
|
+
with Pool() as p:
|
318
|
+
for r in p.starmap(process,
|
319
|
+
[(lfe, pole_width, machine, bch)
|
320
|
+
for bch in zip(*[r['f']
|
321
|
+
for r in results])]):
|
322
|
+
torque = np.mean(r.pop('torque'))
|
323
|
+
r['torque'] = torque
|
324
|
+
r.update(_psidq_ldq(r, nlresults))
|
325
|
+
postp.append(r)
|
326
|
+
else:
|
327
|
+
for r in [process(lfe, pole_width, machine, bch)
|
328
|
+
for bch in zip(*[r['f'] for r in results])]:
|
329
|
+
torque = np.mean(r.pop('torque'))
|
330
|
+
r['torque'] = torque
|
331
|
+
r.update(_psidq_ldq(r, nlresults))
|
332
|
+
postp.append(r)
|
305
333
|
|
306
334
|
r1 = postp[0]['r1']
|
307
335
|
i1 = [r['i1'] for r in postp][::num_beta_steps]
|
@@ -396,6 +424,7 @@ def process(lfe, pole_width, machine, bch):
|
|
396
424
|
n = len(rotpos[0])
|
397
425
|
currents = [bch[0]['flux'][k][0]['current_k'][:n]
|
398
426
|
for k in bch[0]['flux']]
|
427
|
+
|
399
428
|
if len(pole_width) > 1:
|
400
429
|
# check homogenity:
|
401
430
|
if np.diff([len(d) for d in displ]).any():
|
@@ -427,6 +456,9 @@ def process(lfe, pole_width, machine, bch):
|
|
427
456
|
for ux in bch[0]['flux'][k][0]['voltage_dpsi'][:-1]]
|
428
457
|
for k in bch[0]['flux']}
|
429
458
|
emf = [voltage[k][:n] for k in voltage]
|
459
|
+
fluxxy = {k: [scale_factor * np.array(flx)
|
460
|
+
for flx in bch[0]['flux'][k][0]['flux_k']]
|
461
|
+
for k in bch[0]['flux']}
|
430
462
|
flux = [fluxxy[k][:n] for k in fluxxy]
|
431
463
|
|
432
464
|
pos = (rotpos[0]/np.pi*180)
|
@@ -485,7 +517,6 @@ def process(lfe, pole_width, machine, bch):
|
|
485
517
|
except KeyError as exc:
|
486
518
|
#logger.warning("missing key %s", exc)
|
487
519
|
pass
|
488
|
-
|
489
520
|
return {
|
490
521
|
'weights': weights.tolist(),
|
491
522
|
'pos': pos.tolist(), 'r1': r1,
|
@@ -646,13 +677,20 @@ def _draw_vertical_slots(ax,
|
|
646
677
|
color = _get_colors(color, delta)
|
647
678
|
taus = 2*np.pi/Q
|
648
679
|
for n in range(Q):
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
680
|
+
beta0 = np.linspace(n*taus, n*taus + taus/2-alpha[0], 5)
|
681
|
+
beta1 = np.linspace(n*taus, n*taus + taus/2-alpha[1], 5)
|
682
|
+
xr = np.concatenate((
|
683
|
+
r[0]*np.cos(beta0), r[1]*np.cos(beta1[::-1])))+xoff
|
684
|
+
yr = np.concatenate((
|
685
|
+
r[0]*np.sin(beta0), r[1]*np.sin(beta1[::-1])))+yoff
|
686
|
+
ax.fill(xr, yr, color=color[0])
|
687
|
+
beta0 = np.linspace(n*taus + taus/2+alpha[0], (n+1)*taus, 5)
|
688
|
+
beta1 = np.linspace(n*taus + taus/2+alpha[1], (n+1)*taus, 5)
|
689
|
+
xr = np.concatenate((
|
690
|
+
r[0]*np.cos(beta0), r[1]*np.cos(beta1[::-1])))
|
691
|
+
yr = np.concatenate((
|
692
|
+
r[0]*np.sin(beta0), r[1]*np.sin(beta1[::-1])))
|
693
|
+
ax.fill(xr, yr, color=color[0])
|
656
694
|
|
657
695
|
|
658
696
|
def vertical_plot(machine, ax):
|
@@ -669,7 +707,7 @@ def vertical_plot(machine, ax):
|
|
669
707
|
model_type = machine['afmtype'][0:4]
|
670
708
|
dy1 = machine['outer_diam']*1e3
|
671
709
|
dy2 = machine['inner_diam']*1e3
|
672
|
-
rel_magn_width = machine['magnet']['afm_rotor']['rel_magn_width']
|
710
|
+
rel_magn_width = max(machine['magnet']['afm_rotor']['rel_magn_width'])
|
673
711
|
Q = machine['stator']['num_slots']
|
674
712
|
slot_width = machine['stator']['afm_stator']['slot_width']*1e3
|
675
713
|
poles = machine['poles']
|
@@ -818,7 +856,7 @@ def horizontal_plot(machine, ax):
|
|
818
856
|
model_type = machine['afmtype'][0:4]
|
819
857
|
dy1 = machine['outer_diam']*1e3
|
820
858
|
dy2 = machine['inner_diam']*1e3
|
821
|
-
rel_magn_width = machine['magnet']['afm_rotor']['rel_magn_width']
|
859
|
+
rel_magn_width = max(machine['magnet']['afm_rotor']['rel_magn_width'])
|
822
860
|
magn_height = machine['magnet']['afm_rotor']['magn_height']*1e3
|
823
861
|
magn_yoke_height = machine['magnet']['afm_rotor']['yoke_height']*1e3
|
824
862
|
|
@@ -911,6 +949,14 @@ class AFPM:
|
|
911
949
|
except KeyError:
|
912
950
|
raise ValueError("missing key afmtype")
|
913
951
|
|
952
|
+
if np.isscalar(machine['magnet']['afm_rotor']['rel_magn_width']):
|
953
|
+
rmagw = num_slices*[machine['magnet']['afm_rotor']['rel_magn_width']]
|
954
|
+
else:
|
955
|
+
rmagw = machine['magnet']['afm_rotor']['rel_magn_width']
|
956
|
+
if len(rmagw) == 1:
|
957
|
+
rmagw = num_slices*list(rmagw)
|
958
|
+
elif num_slices != len(rmagw):
|
959
|
+
num_slices = len(rmagw)
|
914
960
|
lfe = get_arm_lengths(machine['outer_diam'],
|
915
961
|
machine['inner_diam'],
|
916
962
|
num_slices)
|
@@ -934,11 +980,17 @@ class AFPM:
|
|
934
980
|
"name": "pole_width"},
|
935
981
|
{"values": lfe,
|
936
982
|
"name": "lfe"},
|
983
|
+
{"values": rmagw,
|
984
|
+
"name": "magnet.afm_rotor.rel_magn_width"},
|
937
985
|
{"values": linspeed, "name": "speed"}
|
938
986
|
]
|
939
987
|
}
|
988
|
+
|
940
989
|
machine['pole_width'] = np.pi * machine['inner_diam']/machine['poles']
|
941
990
|
machine['lfe'] = machine['outer_diam'] - machine['inner_diam']
|
991
|
+
machine['magnet']['afm_rotor']['rel_magn_width'] = max(
|
992
|
+
machine['magnet']['afm_rotor']['rel_magn_width'])
|
993
|
+
|
942
994
|
simulation['skew_displ'] = (simulation.get('skew_angle', 0)/180 * np.pi
|
943
995
|
* machine['inner_diam'])
|
944
996
|
nlresults = {}
|
femagtools/multiproc.py
CHANGED
@@ -56,7 +56,8 @@ class ProgressLogger(threading.Thread):
|
|
56
56
|
["progress_logger",
|
57
57
|
f"{self.numTot}:{numOf}:{percent}:{' '.join(summary)}"])
|
58
58
|
else:
|
59
|
-
|
59
|
+
# TODO: log message might be misleading
|
60
|
+
logger.debug('collecting FE losses ...')
|
60
61
|
return
|
61
62
|
|
62
63
|
def stop(self):
|
femagtools/plot/__init__.py
CHANGED
femagtools/plot/bch.py
CHANGED
@@ -22,6 +22,26 @@ except ImportError: # ModuleNotFoundError:
|
|
22
22
|
logger = logging.getLogger("femagtools.plot.bch")
|
23
23
|
|
24
24
|
|
25
|
+
def find_peaks_and_valleys(t, y):
|
26
|
+
""" return peaks and valleys of y with maximum amplitude
|
27
|
+
"""
|
28
|
+
peaks = (np.diff(np.sign(np.diff(y))) < 0).nonzero()[0] + 1
|
29
|
+
if len(peaks > 0):
|
30
|
+
ip = np.argmax(y[peaks])
|
31
|
+
pv = {'yp': y[peaks][ip], 'tp': t[peaks][ip]}
|
32
|
+
else:
|
33
|
+
pv = {'yp': [], 'tp': []}
|
34
|
+
valleys = (np.diff(np.sign(np.diff(y))) > 0).nonzero()[0] + 1
|
35
|
+
if len(valleys > 0):
|
36
|
+
iv = np.argmin(y[valleys])
|
37
|
+
pv.update({'yv': y[valleys][iv], 'tv': t[valleys][iv]})
|
38
|
+
else:
|
39
|
+
pv.update({'yv': [], 'tv': []})
|
40
|
+
pv.update({'peaks': y[peaks], 'valleys': y[valleys],
|
41
|
+
'tpeaks': t[peaks], 'tvalleys': t[valleys]})
|
42
|
+
return pv
|
43
|
+
|
44
|
+
|
25
45
|
def _create_3d_axis():
|
26
46
|
"""creates a subplot with 3d projection if one does not already exist"""
|
27
47
|
from matplotlib.projections import get_projection_class
|
@@ -511,30 +531,62 @@ def transientsc(bch, title=''):
|
|
511
531
|
ax.grid(True)
|
512
532
|
istat = np.array([bch.scData[i]
|
513
533
|
for i in ('ia', 'ib', 'ic')])
|
534
|
+
pv = [find_peaks_and_valleys(
|
535
|
+
np.array(bch.scData['time']), i1)
|
536
|
+
for i1 in istat]
|
537
|
+
try:
|
538
|
+
ipvmax = np.argmax(
|
539
|
+
[y['yp'] if np.abs(y['yp']) > np.abs(y['yv']) else y['yv']
|
540
|
+
for y in pv])
|
541
|
+
imax = pv[ipvmax]['yp'] if np.abs(pv[ipvmax]['yp']) > np.abs(pv[ipvmax]['yv']) else pv[ipvmax]['yv']
|
542
|
+
except KeyError:
|
543
|
+
pass
|
514
544
|
if np.max(istat) > 4000:
|
515
545
|
istat *= 1e-3
|
546
|
+
imax *= 1e-3
|
516
547
|
ax.set_title('Currents / kA')
|
517
548
|
else:
|
518
549
|
ax.set_title('Currents / A')
|
519
550
|
|
520
551
|
for i, iph in zip(('ia', 'ib', 'ic'), istat):
|
521
552
|
ax.plot(bch.scData['time'], iph, label=i)
|
553
|
+
try:
|
554
|
+
ax.plot([pv[ipvmax]['tp']], [imax], '.')
|
555
|
+
ax.annotate(f'Imax = {imax:.1f}',
|
556
|
+
xy=(pv[ipvmax]['tp'], imax),
|
557
|
+
xytext=(pv[ipvmax]['tp']+0.01, imax))
|
558
|
+
except NameError:
|
559
|
+
pass
|
522
560
|
ax.set_xlabel('Time / s')
|
523
561
|
ax.legend()
|
524
562
|
|
525
563
|
row = 2
|
526
564
|
plt.subplot(rows, cols, row)
|
527
565
|
ax = plt.gca()
|
528
|
-
|
566
|
+
pv = find_peaks_and_valleys(
|
567
|
+
np.array(bch.scData['time']), np.array(bch.scData['torque']))
|
568
|
+
try:
|
569
|
+
tqmax = pv['yp'] if np.abs(pv['yp']) > np.abs(pv['yv']) else pv['yv']
|
570
|
+
tp = pv['tp'] if np.abs(pv['yp']) > np.abs(pv['yv']) else pv['tv']
|
571
|
+
except KeyError:
|
572
|
+
pass
|
529
573
|
torque = np.array(bch.scData['torque'])
|
530
574
|
if np.max(torque) > 4000:
|
531
575
|
torque *= 1e-3
|
576
|
+
tqmax *= 1e-3
|
532
577
|
ax.set_title('Torque / kNm')
|
533
578
|
else:
|
534
579
|
ax.set_title('Torque / Nm')
|
535
580
|
|
536
581
|
ax.grid(True)
|
537
582
|
ax.plot(bch.scData['time'], torque)
|
583
|
+
try:
|
584
|
+
ax.plot([tp], [tqmax], '.')
|
585
|
+
ax.annotate(f'Tmax = {tqmax:.1f}',
|
586
|
+
xy=(tp, tqmax),
|
587
|
+
xytext=(tp+0.01, tqmax))
|
588
|
+
except NameError:
|
589
|
+
pass
|
538
590
|
ax.set_xlabel('Time / s')
|
539
591
|
|
540
592
|
fig.tight_layout(h_pad=2)
|
@@ -560,8 +612,10 @@ def transientsc_demag(demag, magnet=0, title='', ax=0):
|
|
560
612
|
label='H Max {:4.2f} kA/m'.format(max(hmax)))
|
561
613
|
ax.plot(pos, havg,
|
562
614
|
label='H Avg {:4.2f} kA/m'.format(max(havg)))
|
563
|
-
|
564
|
-
|
615
|
+
if len(hclim) > 1:
|
616
|
+
ax.plot([pos[0], pos[-1]], hclim, color='C3', linestyle='dashed',
|
617
|
+
label='Hc {:4.2f} kA/m'.format(hclim[0]))
|
618
|
+
|
565
619
|
ax.set_xlabel('Rotor Position / °')
|
566
620
|
ax.grid(True)
|
567
621
|
if magnet:
|
@@ -0,0 +1,100 @@
|
|
1
|
+
"""
|
2
|
+
Create longitudinal drawing of radial flux machine
|
3
|
+
"""
|
4
|
+
import matplotlib.pyplot as plt
|
5
|
+
import matplotlib.patches as pch
|
6
|
+
|
7
|
+
def _draw_shaft(ax, dy2, lfe):
|
8
|
+
xx = (0.0, lfe, lfe, 0.0)
|
9
|
+
yy = (dy2/2, dy2/2, -dy2/2, -dy2/2)
|
10
|
+
ax.fill(xx, yy,
|
11
|
+
facecolor='lightgrey',
|
12
|
+
edgecolor='black',
|
13
|
+
linewidth=0)
|
14
|
+
xx = (-lfe/4, lfe+lfe/4, lfe+lfe/4, -lfe/4)
|
15
|
+
yy = (dy2/4, dy2/4, -dy2/4, -dy2/4)
|
16
|
+
ax.fill(xx, yy,
|
17
|
+
facecolor='lightgrey',
|
18
|
+
edgecolor='black',
|
19
|
+
linewidth=0)
|
20
|
+
|
21
|
+
def _draw_rotor(ax, da1, dy2, lfe):
|
22
|
+
ag = 0.02*da1
|
23
|
+
xx = (0.0, lfe, lfe, 0.0)
|
24
|
+
yy = (dy2/2, dy2/2, da1/2-ag, da1/2-ag)
|
25
|
+
ax.fill(xx, yy,
|
26
|
+
facecolor='skyblue',
|
27
|
+
edgecolor='black',
|
28
|
+
linewidth=0)
|
29
|
+
yy = (-dy2/2, -dy2/2, -da1/2+ag, -da1/2+ag)
|
30
|
+
ax.fill(xx, yy,
|
31
|
+
facecolor='skyblue',
|
32
|
+
edgecolor='black',
|
33
|
+
linewidth=0)
|
34
|
+
|
35
|
+
def _draw_stator(ax, da1, dy1, lfe):
|
36
|
+
xx = (0.0, lfe, lfe, 0.0)
|
37
|
+
yy = (da1/2, da1/2, dy1/2, dy1/2)
|
38
|
+
# yoke
|
39
|
+
ax.fill(xx, yy,
|
40
|
+
facecolor='skyblue',
|
41
|
+
edgecolor='black',
|
42
|
+
linewidth=0)
|
43
|
+
|
44
|
+
yy = (-da1/2, -da1/2, -dy1/2, -dy1/2)
|
45
|
+
ax.fill(xx, yy,
|
46
|
+
facecolor='skyblue',
|
47
|
+
edgecolor='black',
|
48
|
+
linewidth=0)
|
49
|
+
|
50
|
+
# winding
|
51
|
+
yh = (dy1-da1)/2
|
52
|
+
xx = (-yh/2, 0, 0, -yh/2)
|
53
|
+
yy = (da1/2, da1/2, dy1/2-yh/2, dy1/2-yh/2)
|
54
|
+
ax.fill(xx, yy, facecolor='gold',
|
55
|
+
edgecolor='black',
|
56
|
+
linewidth=0)
|
57
|
+
|
58
|
+
xx = (lfe, lfe+yh/2, lfe+yh/2, lfe)
|
59
|
+
ax.fill(xx, yy, facecolor='gold',
|
60
|
+
edgecolor='black',
|
61
|
+
linewidth=0)
|
62
|
+
|
63
|
+
yy = (-da1/2, -da1/2, -dy1/2+yh/2, -dy1/2+yh/2)
|
64
|
+
ax.fill(xx, yy, facecolor='gold',
|
65
|
+
edgecolor='black',
|
66
|
+
linewidth=0)
|
67
|
+
|
68
|
+
xx = (-yh/2, 0, 0, -yh/2)
|
69
|
+
ax.fill(xx, yy, facecolor='gold',
|
70
|
+
edgecolor='black',
|
71
|
+
linewidth=0)
|
72
|
+
|
73
|
+
def machine(machine, ax):
|
74
|
+
dy2 = machine['inner_diam']*1e3
|
75
|
+
dy1 = machine['outer_diam']*1e3
|
76
|
+
da1 = machine['bore_diam']*1e3
|
77
|
+
lfe = machine['lfe']*1e3
|
78
|
+
|
79
|
+
_draw_rotor(ax, da1, dy2, lfe)
|
80
|
+
_draw_stator(ax, da1, dy1, lfe)
|
81
|
+
_draw_shaft(ax, dy2, lfe)
|
82
|
+
ax.set_aspect('equal')
|
83
|
+
|
84
|
+
for loc, spine in ax.spines.items():
|
85
|
+
spine.set_color('none') # don't draw spine
|
86
|
+
#ax.yaxis.set_ticks([])
|
87
|
+
#ax.xaxis.set_ticks([])
|
88
|
+
|
89
|
+
|
90
|
+
if __name__ == '__main__':
|
91
|
+
machine1 = {
|
92
|
+
"outer_diam": 0.2442,
|
93
|
+
"bore_diam": 0.179,
|
94
|
+
"inner_diam": 0.06,
|
95
|
+
"airgap": 0.7e-3,
|
96
|
+
"lfe": 0.083,
|
97
|
+
}
|
98
|
+
fig, ax = plt.subplots()
|
99
|
+
machine(machine1, ax)
|
100
|
+
plt.show()
|
femagtools/poc.py
CHANGED
@@ -75,6 +75,7 @@ class Poc:
|
|
75
75
|
if self.pole_pitch:
|
76
76
|
content.append("{0}".format(self.pole_pitch))
|
77
77
|
if self.pocType in ['fun', 'har', 'hsp']:
|
78
|
+
self.data_check()
|
78
79
|
func_steps = len(self.func_current)
|
79
80
|
content += [f"{self.pocType}", f"{func_steps}"]
|
80
81
|
if (self.pocType == 'fun' and
|
@@ -122,6 +123,7 @@ class Poc:
|
|
122
123
|
import re
|
123
124
|
for i in range(func_steps-1):
|
124
125
|
l = re.split(';|\t|,| ', pocfile.readline().strip())
|
126
|
+
l = [i for i in l if i] # remove empty items
|
125
127
|
if len(l) > 2:
|
126
128
|
self.harmonic_id.append(int(l[0]))
|
127
129
|
self.func_current.append(float(l[1]))
|
@@ -129,6 +131,7 @@ class Poc:
|
|
129
131
|
else:
|
130
132
|
self.func_current.append(float(l[0]))
|
131
133
|
self.func_phi.append(float(l[1]))
|
134
|
+
self.data_check()
|
132
135
|
else:
|
133
136
|
self.shape_current=self.pocType
|
134
137
|
self.pocType='Function'
|
@@ -139,6 +142,13 @@ class Poc:
|
|
139
142
|
except ValueError:
|
140
143
|
pass
|
141
144
|
|
145
|
+
def data_check( self ):
|
146
|
+
"""simple phi data increasing check"""
|
147
|
+
import numpy as np
|
148
|
+
if (not np.all(np.diff(self.func_phi) > 0)
|
149
|
+
and np.all(np.diff(self.func_current) > 0)):
|
150
|
+
self.func_phi, self.func_current = self.func_current, self.func_phi
|
151
|
+
|
142
152
|
def getProps( self ):
|
143
153
|
keys=['key_winding',
|
144
154
|
'phi_voltage_winding',
|
femagtools/utils.py
CHANGED
femagtools/zmq.py
CHANGED
@@ -80,6 +80,9 @@ class SubscriberTask(threading.Thread):
|
|
80
80
|
notify = None
|
81
81
|
notify_send_header = set()
|
82
82
|
notify_send_data = dict()
|
83
|
+
# progress, xydata and this entries of this list
|
84
|
+
# will send only only once per timestep
|
85
|
+
simple_data = ['license']
|
83
86
|
|
84
87
|
def __init__(self, **kwargs):
|
85
88
|
threading.Thread.__init__(self)
|
@@ -92,7 +95,8 @@ class SubscriberTask(threading.Thread):
|
|
92
95
|
self.header = kwargs.get('header')
|
93
96
|
self.num_cur_steps = kwargs.get('num_cur_steps', None)
|
94
97
|
SubscriberTask.curve_label = kwargs.get('curve_label', '')
|
95
|
-
SubscriberTask.timestep = kwargs.get('timestep',
|
98
|
+
SubscriberTask.timestep = kwargs.get('timestep', 2)
|
99
|
+
|
96
100
|
if not self.host:
|
97
101
|
self.host = 'localhost'
|
98
102
|
if not self.header:
|
@@ -145,7 +149,7 @@ class SubscriberTask(threading.Thread):
|
|
145
149
|
SubscriberTask.percent_list = []
|
146
150
|
|
147
151
|
def send_notify():
|
148
|
-
logger.debug(f"Send loop: {SubscriberTask.notify_send_loop}")
|
152
|
+
logger.debug(f"Send loop: {SubscriberTask.notify_send_loop}, timestep: {SubscriberTask.timestep}")
|
149
153
|
while SubscriberTask.notify_send_loop:
|
150
154
|
if 'progress_logger' in SubscriberTask.notify_send_header:
|
151
155
|
# collect data from different threads
|
@@ -153,13 +157,20 @@ class SubscriberTask(threading.Thread):
|
|
153
157
|
numTot = len(SubscriberTask.percent_list)
|
154
158
|
d = json.loads(SubscriberTask.notify_send_data.get('progress_logger')[1])
|
155
159
|
d['percent'] = sum(SubscriberTask.percent_list) / numTot
|
156
|
-
d['subtitle'] = f"{SubscriberTask.percent_list.count(100)} of {numTot}"
|
160
|
+
d['subtitle'] = f"{SubscriberTask.percent_list.count(100)} of {numTot}" if numTot > 1 else ''
|
157
161
|
SubscriberTask.notify(['progress_logger', json.dumps(d)])
|
158
162
|
if 'xyplot' in SubscriberTask.notify_send_header:
|
159
163
|
SubscriberTask.notify([s.decode('latin1')
|
160
164
|
for s in SubscriberTask.notify_send_data.get('xyplot')])
|
161
165
|
SubscriberTask.notify_send_header.remove('xyplot')
|
162
166
|
|
167
|
+
# simple
|
168
|
+
for sdata in SubscriberTask.simple_data:
|
169
|
+
if sdata in SubscriberTask.notify_send_header:
|
170
|
+
SubscriberTask.notify([s.decode('latin1')
|
171
|
+
for s in SubscriberTask.notify_send_data.get(sdata)])
|
172
|
+
SubscriberTask.notify_send_header.remove(sdata)
|
173
|
+
|
163
174
|
time.sleep(abs(SubscriberTask.timestep))
|
164
175
|
logger.debug(f"Send Finished loop: {SubscriberTask.notify_send_loop}")
|
165
176
|
|
@@ -196,7 +207,14 @@ class SubscriberTask(threading.Thread):
|
|
196
207
|
SubscriberTask.notify_send_header.add('xyplot')
|
197
208
|
continue
|
198
209
|
|
199
|
-
|
210
|
+
# simple
|
211
|
+
for sdata in SubscriberTask.simple_data:
|
212
|
+
if response[0] == sdata.encode() and sdata.encode() in self.header:
|
213
|
+
SubscriberTask.notify_send_header.add(sdata)
|
214
|
+
SubscriberTask.notify_send_data[sdata] = response
|
215
|
+
continue
|
216
|
+
|
217
|
+
if response[0] not in self.header:
|
200
218
|
self.notify([s.decode('latin1') for s in response])
|
201
219
|
|
202
220
|
except Exception:
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: femagtools
|
3
|
-
Version: 1.8.
|
3
|
+
Version: 1.8.6
|
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=2SMaY7V-Yp8JBGAb9m9bsHhX8WWkzbzADhc7yCeh0Lw,1600
|
2
2
|
femagtools/airgap.py,sha256=hELJXe52yUw82JwZ1tGUXUtRhMG2_WSUBVeGkTZSAM8,1900
|
3
3
|
femagtools/amazon.py,sha256=O1ICuv21XDAJi1qK1Sigs2TdS6hDZP19OzvmE2t76wU,12069
|
4
4
|
femagtools/amela.py,sha256=RFTuQ5EcX19G2YJchnktr6j62mNptrdTreShQDOeuKA,13874
|
5
5
|
femagtools/asm.py,sha256=CiL0KWaF4P7O6-VwmGLdva_icwmPrPiI-TFQ19XYTKk,7660
|
6
|
-
femagtools/bch.py,sha256=
|
6
|
+
femagtools/bch.py,sha256=PSQmGp2zuAqMYnE9r-zZdehxVcS8BKtAunpBEZTn9uA,74131
|
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
|
@@ -15,7 +15,7 @@ femagtools/dakotaout.py,sha256=6nn0PXsB40mPKiQLenqAtHy0KXCO7kvqqQ-aD2JhQvw,5573
|
|
15
15
|
femagtools/docker.py,sha256=XDVmLBB0z4sZZpcrx7Wbm84xl4ksj7aqn5-ZOPxdxm4,7460
|
16
16
|
femagtools/ecloss.py,sha256=kTsE9Lx6nt6Ez9PBfD58hPMcnH2PxSc95zJaYMCQd5Q,33957
|
17
17
|
femagtools/erg.py,sha256=IXKq76P9qLt_ssNOP78v8Qizk3J2Zg80yaKDSjzwoJE,1224
|
18
|
-
femagtools/femag.py,sha256=
|
18
|
+
femagtools/femag.py,sha256=MDCw2k6MHF69N99turE_5T5qaciKqnREocev6x_6_fU,47479
|
19
19
|
femagtools/forcedens.py,sha256=7NNv75Vg9vQ_fy8W4kM2rlSO970zaSmeurhPmdAxsOU,8485
|
20
20
|
femagtools/fsl.py,sha256=Bq6bVykmU0Ih5YTbxhRAlCMn2fx1UE2G2UxGI83EKGQ,37072
|
21
21
|
femagtools/getset.py,sha256=yJ6Em35DeWK7WNZW0qjjS5s7LUkVh5mbgxF59HHm5FM,3017
|
@@ -33,35 +33,35 @@ femagtools/mcv.py,sha256=1yXaQIQEC63WmInnt0HggeFKRk2PmrPC90_uGd5-dOw,41696
|
|
33
33
|
femagtools/me.py,sha256=z6RJkvSbgMmorCQTxKvq44uIYKh82uYYExjkNePJCmE,1813
|
34
34
|
femagtools/model.py,sha256=dk9x-iqRzgOTdTCeU_ynUZGb1bt4FvU1ZGMPXytMbUg,17965
|
35
35
|
femagtools/moproblem.py,sha256=kOP8pRdD8YXz28_M2WKnFgl3eeJ7tqg49ohoazsmUOg,2825
|
36
|
-
femagtools/multiproc.py,sha256=
|
36
|
+
femagtools/multiproc.py,sha256=Y8nx0W4NgRoG6UWO6TUD1drx216xnzSYuBbisCHhqrY,9107
|
37
37
|
femagtools/mxw2msh.py,sha256=CIIqAvfs8U-A0OfuOAoDaqNSmoMSHSI_tW1CPFRCP5E,2151
|
38
38
|
femagtools/nc.py,sha256=bAj3iurE9WaovoCi76ry2aJZJ6rC1zO6xWrfsSD6lrc,15160
|
39
39
|
femagtools/netlist.py,sha256=CSCl8setLZ_L8DCnNWaNA3-wLe1yo-fmzARZoVvYfaA,2052
|
40
40
|
femagtools/ntib.py,sha256=76g1ZO3Fq_kN-HTMBvaKvJmMMlJMyEPFeNAcJPq3w7Y,3099
|
41
41
|
femagtools/opt.py,sha256=wBU0yh3hZlNti_zfIvtKcPg1EJrnE3I1BqmVxLGWixU,8753
|
42
42
|
femagtools/parstudy.py,sha256=lLz2SIxUJRc1YV54vW-Zl1h_MvP9mHMtl1RJa_ich3c,19734
|
43
|
-
femagtools/poc.py,sha256=
|
43
|
+
femagtools/poc.py,sha256=yPWmpi8Q2g7NmpAi2YV5ezyo0VUj67EK0tcX2wikerw,7207
|
44
44
|
femagtools/semi_fea.py,sha256=WZtYKrzhDruETyuEW2kpiNp9OaA7Hheq3qJiAIYtsjg,3475
|
45
45
|
femagtools/tks.py,sha256=C3lDdS91Yikf3cMnW-OEqmie-q6S24T81cCFrzwOyeI,7532
|
46
46
|
femagtools/ts.py,sha256=x9aCMVASjdBZuyI2pJGMyi1dveGFd_pWQ20cZ-l_moc,47216
|
47
|
-
femagtools/utils.py,sha256=
|
47
|
+
femagtools/utils.py,sha256=dJkQ5xsoVMzSEB5-2hEiwe2of9mLmsDo8nkrnSN-gPE,1643
|
48
48
|
femagtools/vbf.py,sha256=9XGfhftmD9carU8ByQ5DwqoR4daq5mJ39eMqruwml0Q,2444
|
49
49
|
femagtools/vtu.py,sha256=Sf83dHIfCKY2km-MIUHKKoj-JKN4PDX7kkPLZXyIYY4,10723
|
50
50
|
femagtools/windings.py,sha256=RS3QSx1JY0FXzItDuWimC9zYzRxq9n6BbY5fZt1dMFg,23780
|
51
|
-
femagtools/zmq.py,sha256=
|
51
|
+
femagtools/zmq.py,sha256=HY8U7dxXkgE48151nvLcnLPa8OFBZcZTrB2XcjBc0Y4,9413
|
52
52
|
femagtools/dxfsl/__init__.py,sha256=MywcCdpKPKs4qJBJJgeDsikJFJ2P48dbTuNk303f5pM,76
|
53
|
-
femagtools/dxfsl/area.py,sha256=
|
53
|
+
femagtools/dxfsl/area.py,sha256=CpTMRBF8_AJmJMkkn-LgRv27U5xJ5Ohhd2ppRvESPNU,69757
|
54
54
|
femagtools/dxfsl/areabuilder.py,sha256=6dfWryYjXzGIVDOsX2zb1VKIhUzmpL43XhF-wtdesAg,35882
|
55
55
|
femagtools/dxfsl/concat.py,sha256=F6scwesxyOmfmKQ5kGspNCxA71Yz6QgxFL7lTj3hsaI,13385
|
56
|
-
femagtools/dxfsl/conv.py,sha256=
|
57
|
-
femagtools/dxfsl/converter.py,sha256=
|
56
|
+
femagtools/dxfsl/conv.py,sha256=rAG_r2twWtcZyLKe8L8gYcC-n-JMG-dK1iMmd9yviTQ,12237
|
57
|
+
femagtools/dxfsl/converter.py,sha256=PQ92kyRIxKWdrlVpNSvIq_Ska-RDMC26RVM1rluPVk0,40826
|
58
58
|
femagtools/dxfsl/corner.py,sha256=-XPBcnEau-2-SRHLYzlBqCQGaFfgm_DH2qR1mSaFoAs,1311
|
59
59
|
femagtools/dxfsl/dumprenderer.py,sha256=n4AvInjvGIaC2iKZtQaYXXDyJVSQ3uEOFOLD4-xfKRY,1861
|
60
60
|
femagtools/dxfsl/dxfparser.py,sha256=kyXG0kZfNyOgn96MqBgP8RhOQhppfB5NbyRNNybs1C0,13451
|
61
61
|
femagtools/dxfsl/femparser.py,sha256=O8940Q1Mz8MKng6W8M3s9KfTvhDLJ56tfQWtZEW3xMM,2134
|
62
62
|
femagtools/dxfsl/fslrenderer.py,sha256=gaHBJwqPt7fVz-fyphCb-xppmIFvu72zBpeB18eAvko,27826
|
63
63
|
femagtools/dxfsl/functions.py,sha256=1RFT2YPR_rTJSKtTqIoO8Z-s_kXKIp95zed83SM0gZg,12784
|
64
|
-
femagtools/dxfsl/geom.py,sha256=
|
64
|
+
femagtools/dxfsl/geom.py,sha256=bUa_5103OdNJTzEexYYPvMs9Kx1BSNbvWL9ekETWmI4,178082
|
65
65
|
femagtools/dxfsl/journal.py,sha256=r4z52av3k95MjwzypgUJpj8sSAeQoJsS81Uqs1IBLVw,4265
|
66
66
|
femagtools/dxfsl/machine.py,sha256=_GmGQdrH7yCkRdCCdkm4yALHS1Gwof77zJOZbWtgRPo,57990
|
67
67
|
femagtools/dxfsl/plotrenderer.py,sha256=q2cORuxJEf1Ws6oCY9c0gF6N3kDrcI6WOz3u5Vl6R_c,13823
|
@@ -69,7 +69,7 @@ femagtools/dxfsl/shape.py,sha256=uQqbgXIA2_KP2XRdhCfVfGWjcjwzhJ5t9RhiqR9R98c,616
|
|
69
69
|
femagtools/dxfsl/svgparser.py,sha256=RY2TU9MK6gOaNmI6w6RNqcw7H9YGmK-NUwvdylKBcsE,3763
|
70
70
|
femagtools/dxfsl/symmetry.py,sha256=dXfZVIqT49nbMirY5YVaRPi8kNB8reaiq-eIbhw1Z54,43936
|
71
71
|
femagtools/machine/__init__.py,sha256=B7yeRZzf29NWCWy8C8iJFdTr9bszAoMRcVEpblhCeg4,7256
|
72
|
-
femagtools/machine/afpm.py,sha256=
|
72
|
+
femagtools/machine/afpm.py,sha256=rUByVyzNhT0BEUgTCj-HuU4Wbi4PWVAOeOZfa23Cejk,37980
|
73
73
|
femagtools/machine/effloss.py,sha256=gOgVdAr703Vh9T2Ht14of_I-95QOkH5qXmm11bfHK7s,14414
|
74
74
|
femagtools/machine/im.py,sha256=isMSoCnIk4Hj47MwBNP5PW7a2rI-7N35A9zHGOSl43s,38111
|
75
75
|
femagtools/machine/pm.py,sha256=C4vDdPIsIRUKtzY3b1RNT1v37p1uP3pMUduftNejcPc,68129
|
@@ -83,12 +83,13 @@ femagtools/moo/problem.py,sha256=McIGKAXK97Jygumns0qmFeYxTG6KDRSQj2aENeC9F9A,239
|
|
83
83
|
femagtools/moo/test/AlgorithmTest.py,sha256=KzR1og4bu6NOE61DDKjEMTQdsysmho4LCYmJ6WZoILo,2535
|
84
84
|
femagtools/moo/test/PopulationTest.py,sha256=lG9NeWo0xrslfQRa4tgy1Nj23VJMFIlg_vQ9KUBYnRA,5529
|
85
85
|
femagtools/moo/test/ProblemTest.py,sha256=r5XEfY4LPscDb35TxxPd0lbP3nUmL6_G6vrRo1I3RSg,505
|
86
|
-
femagtools/plot/__init__.py,sha256=
|
87
|
-
femagtools/plot/bch.py,sha256=
|
86
|
+
femagtools/plot/__init__.py,sha256=LFrHy_9L6FxJqhYND2z1534s3ebPXkfXVagFeNA1wWk,978
|
87
|
+
femagtools/plot/bch.py,sha256=Sdy6S_XT6bGnl21V-1XscqTkFUCIy-fCX8PivShI9GY,30754
|
88
88
|
femagtools/plot/char.py,sha256=xv4cNOTorK-fy7eUFhmyR-013TFI2A2999xXKgL2AnA,12469
|
89
89
|
femagtools/plot/fieldlines.py,sha256=_7ykKhnQLeS4fz34pnzovH1gIhcUSKJ3gl1GUgWYix8,1137
|
90
90
|
femagtools/plot/fluxdens.py,sha256=NlexRJ3f_8CgKoWrV82ZIsAXPrLhwj98uOe8_fUks7A,1082
|
91
91
|
femagtools/plot/forcedens.py,sha256=Vloi9czy7qbGXI-Vm7Cow6IfHTsFhCLI1YWduFOR55c,4075
|
92
|
+
femagtools/plot/machine.py,sha256=fVLOZTc19Ru8eXLdtoTeIYsHRWhGLkn_YVZ6qO6KgrE,2654
|
92
93
|
femagtools/plot/mcv.py,sha256=ijZg6KPwZC7sDxEzGEUfVWvDoSEfgcaH-hzQMt7E90I,3671
|
93
94
|
femagtools/plot/nc.py,sha256=kfTifzAMReQZu4UmbHZo1caAK0n7N51lkPj7BU7l1lU,10876
|
94
95
|
femagtools/plot/phasor.py,sha256=5QG1GkXKVksc8P6Q4thKADf6W1l8rDKeArIHFYvbXlw,4858
|
@@ -215,9 +216,9 @@ tests/moo/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
215
216
|
tests/moo/test_algorithm.py,sha256=Em8sFm2vzPmuIzRrBBnUQLU_TYuJHSf-kEeozw0XeX4,2563
|
216
217
|
tests/moo/test_population.py,sha256=FvX9LRCxQx0_E2GxHQ5vKwOYFBQiNbT6Lmv5GmNWjTQ,5471
|
217
218
|
tests/moo/test_problem.py,sha256=ALeP4u7g-dFhfwWL8vxivdrrYzVKPjHMCAXzzgyNZbs,467
|
218
|
-
femagtools-1.8.
|
219
|
-
femagtools-1.8.
|
220
|
-
femagtools-1.8.
|
221
|
-
femagtools-1.8.
|
222
|
-
femagtools-1.8.
|
223
|
-
femagtools-1.8.
|
219
|
+
femagtools-1.8.6.dist-info/LICENSE,sha256=NaQe4uvkszQPJmiRPHecfk-Ab9VSRXo8xQLGNVHTeFo,1362
|
220
|
+
femagtools-1.8.6.dist-info/METADATA,sha256=tI4Q7eHYpIQea6ThRR-t4cUGHGolUaBOwmzxfHktp_E,6190
|
221
|
+
femagtools-1.8.6.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
222
|
+
femagtools-1.8.6.dist-info/entry_points.txt,sha256=jrvOkZPiN44u1sASeu271VRaVIv5V-uRpN0_N5U_R8c,248
|
223
|
+
femagtools-1.8.6.dist-info/top_level.txt,sha256=Ri4YWtU8MZTzNje9IKyXhTakNbsrCynuWdon4Yq94Dc,17
|
224
|
+
femagtools-1.8.6.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|