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 CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  """
4
4
  __title__ = 'femagtools'
5
- __version__ = '1.8.5'
5
+ __version__ = '1.8.6'
6
6
  __author__ = 'Ronald Tanner'
7
7
  __license__ = 'BSD'
8
8
  __copyright__ = 'Copyright 2023-2024 Gamma Technology'
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 re.findall(r'[-0-9.]+',
622
- ''.join(content))]
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})
@@ -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, SimpleProcess, middle_angle
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
- inner_queue = multiprocessing.Queue()
730
- inner_proc = SymSearchProcess(name="Inner", # for logger
731
- queue=inner_queue,
732
- machine=machine_inner,
733
- plt=None, # plot
734
- kind=inner_name,
735
- is_inner=True,
736
- mindist=mindist,
737
- symtol=symtol,
738
- show_plots=show_plots,
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
- inner_queue = multiprocessing.Queue()
765
- inner_proc = BuildInnerProcess(name="Inner", # for logger
766
- queue=inner_queue,
767
- machine=machine_inner,
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.info("make a cut")
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)
@@ -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], args=(p,))[0]
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
- num_slices = kwargs.get('num_slices', 3)
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
- for pw, le, sp in zip(pole_width, lfe, linspeed):
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
- for results in [process(lfe, pole_width, machine, bch)
300
- for bch in zip(*[r['f'] for r in results])]:
301
- torque = np.mean(results.pop('torque'))
302
- results['torque'] = torque
303
- results.update(_psidq_ldq(results, nlresults))
304
- postp.append(results)
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
- beta = np.array([[n*taus+alpha[0], (n+1)*taus-alpha[0]],
650
- [(n+1)*taus-alpha[1], n*taus+alpha[1]]])
651
- ax.fill(np.hstack((r * np.cos(beta[0, 0]),
652
- (r[::-1] * np.cos(beta[0, 1]))))+xoff,
653
- np.hstack((r * np.sin(beta[0, 0]),
654
- (r[::-1] * np.sin(beta[0, 1]))))+yoff,
655
- facecolor=color[0], edgecolor=color[0])
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
- logger.info('collecting FE losses ...')
59
+ # TODO: log message might be misleading
60
+ logger.debug('collecting FE losses ...')
60
61
  return
61
62
 
62
63
  def stop(self):
@@ -1,6 +1,7 @@
1
1
  """Creating plots
2
2
 
3
3
  """
4
+ from .machine import machine
4
5
  from .fluxdens import airgap, airgap_fft
5
6
  from .bch import torque, torque_fft, force, force_fft, \
6
7
  fluxdens_surface, winding_current, winding_flux, \
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
- scale = 1
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
- ax.plot([pos[0], pos[-1]], hclim, color='C3', linestyle='dashed',
564
- label='Hc {:4.2f} kA/m'.format(hclim[0]))
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
@@ -49,7 +49,9 @@ def fft(pos, y, pmod=0):
49
49
  nmax = min(9*npoles, N//2)
50
50
 
51
51
  alfa0 = np.angle(Y[i])
52
+ alfa = np.angle(Y[:nmax])
52
53
 
53
54
  return {'a': a, 'a0': a0, 'T0': T0, 'alfa0': alfa0,
55
+ 'alfa': alfa,
54
56
  'nue': (2*np.abs(Y[:nmax])/N).tolist(),
55
57
  'yi': yx.tolist()}
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', 1)
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
- if response[0] in self.header or b'' in self.header:
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.5
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=AYG-i1TsOTL54WdFZq9UcxAcqn7kj3GFb6Q_xMGw0jc,1600
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=7-Qd8BjxbYjNhmHbZtblsIW3FavjREiSE-RkAHA0TO4,74068
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=gku2PP8rEj8UWRUscD5jYB7kKzlA4lcbd-y2sTdRClQ,47291
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=p2Y4gu-WlGdN9v6aL4IUHPG0bANHUPSE4a9F64wIMoY,9050
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=wMwOxMhPLFRiGPMsKQwWWuGr6UZPzRBajhfVMfXptNU,6794
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=IXMk5ZI7B8CPePT523o_9doTKaaWuFe93AVwkBxkp00,1587
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=fsPvLbL7UB1CarTgixbWclIlVmCCsU4JLTKGEdg1wcU,8508
51
+ femagtools/zmq.py,sha256=HY8U7dxXkgE48151nvLcnLPa8OFBZcZTrB2XcjBc0Y4,9413
52
52
  femagtools/dxfsl/__init__.py,sha256=MywcCdpKPKs4qJBJJgeDsikJFJ2P48dbTuNk303f5pM,76
53
- femagtools/dxfsl/area.py,sha256=CXLf4lagLGGMkGZLfwowpH50djsZkepYSU5F3Juyxqo,69679
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=9ki4PGyKuPpsSifKrBPu5_IvbhePv3sQU-Sq8A64s4w,12606
57
- femagtools/dxfsl/converter.py,sha256=SYz5JWh485EeLA5K4gtz2jsVo8z0CXUjVn5tJ4JoEuM,43453
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=rDOgfYYkhwpR8lf30Tr1sTo-j7kZ300XBAX_gEHw79M,176516
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=6P84lMVGgpnNcZBNkelTMNmaGGjydan_0loZ_n0K7Zc,35658
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=f0yNw9NhadltPIu7zRWwTAY6FgHKeq9ul-3UcnK8Fmk,949
87
- femagtools/plot/bch.py,sha256=_EEPPEqtEPeWco3xlQqUuZft1eF-IXbMNnXyd8pYEJs,28873
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.5.dist-info/LICENSE,sha256=NaQe4uvkszQPJmiRPHecfk-Ab9VSRXo8xQLGNVHTeFo,1362
219
- femagtools-1.8.5.dist-info/METADATA,sha256=CxspB9_deq3AqzLvZWTL8kn0ZpMD6yiUKo67ppIZ1y4,6190
220
- femagtools-1.8.5.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
221
- femagtools-1.8.5.dist-info/entry_points.txt,sha256=jrvOkZPiN44u1sASeu271VRaVIv5V-uRpN0_N5U_R8c,248
222
- femagtools-1.8.5.dist-info/top_level.txt,sha256=Ri4YWtU8MZTzNje9IKyXhTakNbsrCynuWdon4Yq94Dc,17
223
- femagtools-1.8.5.dist-info/RECORD,,
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,,