femagtools 1.8.5__py3-none-any.whl → 1.8.6__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- 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
|