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 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,,