femagtools 1.8.5__py3-none-any.whl → 1.8.7__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
femagtools/__init__.py CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  """
4
4
  __title__ = 'femagtools'
5
- __version__ = '1.8.5'
5
+ __version__ = '1.8.7'
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 = []
@@ -1057,10 +1057,11 @@ class Reader:
1057
1057
  e.g. : idList[-450, -350, -250, -150, -50, 0]
1058
1058
  idList[-500, -400, -300, -200, -100, 0, 0]
1059
1059
  '''
1060
- diff = np.floor(np.abs(np.diff(idList)))
1061
- if idList[-1] == 0 and len(idList) > 2 and \
1062
- diff[-1] == 0:
1060
+ if list(idList).count(0) > 1: # femag writes duplicate id==0 values
1063
1061
  idList = idList[:-1]
1062
+ diff = np.floor(np.abs(np.diff(idList)))
1063
+ if n := np.trim_zeros(np.diff(diff)).size:
1064
+ idList = idList[:-n]
1064
1065
  return idList
1065
1066
 
1066
1067
  def __read_psidq(self, content):
@@ -1085,8 +1086,7 @@ class Reader:
1085
1086
  ncols = ncols-1
1086
1087
 
1087
1088
  id = np.reshape(m[0], (-1, ncols)).T[0]
1088
- if id[0] >= 0:
1089
- id = self.__removeTrailingZero(id)
1089
+ id = self.__removeTrailingZero(id)
1090
1090
  nrows = len(id)
1091
1091
  if nrows > 1 and id[nrows-1] < id[nrows-2]:
1092
1092
  nrows = nrows-1
@@ -1121,8 +1121,7 @@ class Reader:
1121
1121
  ncols = ncols-1
1122
1122
 
1123
1123
  id = np.reshape(m[0], (-1, ncols)).T[0]
1124
- if id[0] >= 0:
1125
- id = self.__removeTrailingZero(id)
1124
+ id = self.__removeTrailingZero(id)
1126
1125
  nrows = len(id)
1127
1126
  if nrows > 1 and id[nrows-1] < id[nrows-2]:
1128
1127
  nrows = nrows-1
@@ -1610,6 +1609,11 @@ class Reader:
1610
1609
  losses['staza'] = floatnan(rec[0])
1611
1610
  losses['stajo'] = floatnan(rec[1])
1612
1611
  losses['total'] += losses['staza']+losses['stajo']
1612
+
1613
+ elif content[i+1].split() == ['Iron', '----']:
1614
+ losses['rotfe'] = sum([floatnan(x) for x in rec])
1615
+ losses['total'] += losses['rotfe']
1616
+
1613
1617
  else:
1614
1618
  losses['rotfe'] = floatnan(rec[1])
1615
1619
  losses['total'] += losses['rotfe']
@@ -1771,6 +1775,9 @@ class Reader:
1771
1775
  def __getattr__(self, k):
1772
1776
  return self.__dict__[k]
1773
1777
 
1778
+ def asdict(self):
1779
+ return {k[0]: k[1] for k in self.items()}
1780
+
1774
1781
  def items(self):
1775
1782
  return [(k, self.get(k)) for k in ('version',
1776
1783
  'type',
femagtools/dxfsl/area.py CHANGED
@@ -435,6 +435,9 @@ class Area(object):
435
435
  self.type == TYPE_WINDINGS or \
436
436
  self.type == TYPE_FD_WINDINGS
437
437
 
438
+ def is_field_winding(self):
439
+ return self.type == TYPE_FD_WINDINGS
440
+
438
441
  def is_magnet(self):
439
442
  return self.type == TYPE_MAGNET_AIRGAP or self.type == TYPE_MAGNET_RECT
440
443
 
femagtools/dxfsl/conv.py CHANGED
@@ -180,12 +180,6 @@ def main():
180
180
  help='create full model (fsl only)',
181
181
  dest='full_model',
182
182
  action="store_true")
183
- argparser.add_argument('--no_processing',
184
- help=(argparse.SUPPRESS if not super_help else
185
- "omit multiprocessing"),
186
- dest='no_processing',
187
- action="store_true",
188
- default=False)
189
183
 
190
184
  args = argparser.parse_args()
191
185
 
@@ -282,8 +276,7 @@ def main():
282
276
  write_id=args.write_id,
283
277
  debug_mode=args.debugger,
284
278
  full_model=args.full_model,
285
- write_journal=args.journal,
286
- no_processing=args.no_processing)
279
+ write_journal=args.journal)
287
280
  keys = ('tot_num_slot', 'num_sl_gen', 'num_poles', 'nodedist',
288
281
  'dy1', 'da1', 'da2', 'dy2', 'agndst', 'name')
289
282
  logger.info("%s", {k: res[k] for k in keys if k in res})
@@ -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
@@ -61,43 +61,6 @@ def handle_process_output(filedes, outfile, log):
61
61
  pass
62
62
 
63
63
 
64
- def get_shortCircuit_parameters(bch, nload):
65
- try:
66
- if nload < 0:
67
- nload = 0
68
- if nload > 2:
69
- nload = 2
70
- if nload > 0:
71
- dqld = bch.dqPar['ld']
72
- dqlq = bch.dqPar['lq']
73
- dqpsim = bch.dqPar['psim']
74
- if len(dqld) <= nload or len(dqlq) <= nload or len(dqpsim) <= nload:
75
- ld = dqld[-1]/bch.armatureLength
76
- lq = dqlq[-1]/bch.armatureLength
77
- psim = dqpsim[-1]/bch.armatureLength
78
- else:
79
- ld = dqld[nload-1]/bch.armatureLength
80
- lq = dqlq[nload-1]/bch.armatureLength
81
- psim = dqpsim[nload-1]/bch.armatureLength
82
- else:
83
- ld = bch.machine['ld']/bch.armatureLength
84
- lq = bch.machine['lq']/bch.armatureLength
85
- psim = bch.machine['psim']/bch.armatureLength
86
- return dict(
87
- r1=bch.machine['r1'],
88
- ld=ld,
89
- lq=lq,
90
- psim=psim,
91
- num_pol_pair=bch.machine['p'],
92
- fc_radius=bch.machine['fc_radius'],
93
- lfe=bch.armatureLength/1e3,
94
- pocfilename=bch.machine['pocfile'],
95
- num_par_wdgs=bch.machine.get('num_par_wdgs', 0),
96
- calculationMode='shortcircuit')
97
- except (KeyError, AttributeError, IndexError):
98
- raise FemagError("missing pm/Rel-Sim results")
99
-
100
-
101
64
  def set_magnet_properties(model, simulation, magnets):
102
65
  """set temperature adapted magnet properties"""
103
66
  if not hasattr(model, 'magnet'):
@@ -449,7 +412,7 @@ class BaseFemag(object):
449
412
 
450
413
  return list(pathlib.Path(self.workdir).glob('*.PROT'))[0].stem
451
414
 
452
- def readResult(self, simulation, bch=None):
415
+ def readResult(self, machine, simulation, bch=None):
453
416
  if simulation:
454
417
  if simulation['calculationMode'] == "fieldcalc":
455
418
  nc = self.read_nc()
@@ -495,38 +458,11 @@ class BaseFemag(object):
495
458
  if simulation['calculationMode'] == 'pm_sym_fast' or \
496
459
  simulation['calculationMode'] == 'torq_calc':
497
460
  if simulation.get('shortCircuit', False):
498
- logger.info("short circuit simulation")
499
- simulation.update(
500
- get_shortCircuit_parameters(bch,
501
- simulation.get('initial', 2)))
502
-
503
- builder = femagtools.fsl.Builder(self.templatedirs)
461
+ from .shortcircuit import shortcircuit
504
462
  set_magnet_properties(self.model, simulation, self.magnets)
505
- fslcmds = (builder.open_model(self.model) +
506
- builder.create_shortcircuit(simulation))
507
- fslfile = 'shortcicuit.fsl'
508
- with open(os.path.join(self.workdir, fslfile), 'w') as f:
509
- f.write('\n'.join(fslcmds))
510
- self.run(fslfile) #, options?
511
- bchfile = self.get_bch_file(self.modelname)
512
- if bchfile:
513
- bchsc = femagtools.bch.Reader()
514
- logger.info("Read BCH {}".format(bchfile))
515
- with io.open(bchfile, encoding='latin1',
516
- errors='ignore') as f:
517
- bchsc.read(f)
518
- bch.scData = bchsc.scData
519
- for w in bch.flux:
520
- try:
521
- bch.flux[w] += bchsc.flux[w]
522
- bch.flux_fft[w] += bchsc.flux_fft[w]
523
- except (KeyError, IndexError):
524
- logging.debug(
525
- "No additional flux data in sc simulation")
526
- break
527
-
528
- bch.torque += bchsc.torque
529
- bch.demag += bchsc.demag
463
+ bch.scData = shortcircuit(self, machine, bch, simulation)
464
+ #bch.torque += bchsc.torque
465
+ #bch.demag += bchsc.demag
530
466
 
531
467
  if 'airgap_induc' in simulation:
532
468
  try:
@@ -699,8 +635,9 @@ class Femag(BaseFemag):
699
635
  setattr(self, "dy2", machine['stator']['dy2'])
700
636
  except:
701
637
  pass
638
+
702
639
  if simulation:
703
- return self.readResult(simulation)
640
+ return self.readResult(machine, simulation)
704
641
 
705
642
  return {'status': 'ok', 'message': self.modelname,
706
643
  'model': self.model.props()}
@@ -801,9 +738,12 @@ class ZmqFemag(BaseFemag):
801
738
  def subscribe(self, notify):
802
739
  """attaches a notify function"""
803
740
  logger.info("Subscribe on '%s' port %d", self.femaghost, self.port+1)
741
+ femagtools.zmq.SubscriberTask.clear()
804
742
  if self.subscriber is None:
743
+ # progress/xyplot at a configured timestep published
744
+ header = [b'progress', b'xyplot', b'license']
805
745
  self.subscriber = femagtools.zmq.SubscriberTask(
806
- port=self.port+1, host=self.femaghost, notify=notify)
746
+ port=self.port+1, host=self.femaghost, notify=notify, header=header)
807
747
  self.subscriber.start()
808
748
  else:
809
749
  # reattach?
@@ -1087,7 +1027,7 @@ class ZmqFemag(BaseFemag):
1087
1027
  response = self.send_request(
1088
1028
  ['CONTROL', f'getfile = {filename}'], timeout=1000)
1089
1029
  return [response[0].decode('latin1'),
1090
- response[1] if len(response) else b'']
1030
+ response[1] if len(response) > 1 else b'']
1091
1031
 
1092
1032
  def exportsvg(self, fslcmds, timeout=10000):
1093
1033
  """get svg format from fsl commands (if any graphic created)
@@ -1156,6 +1096,7 @@ class ZmqFemag(BaseFemag):
1156
1096
  logger.info("Interrupt %s", self.femaghost)
1157
1097
  ctrl.send_string('interrupt')
1158
1098
  ctrl.close()
1099
+ femagtools.zmq.SubscriberTask.clear()
1159
1100
 
1160
1101
  def copy_winding_file(self, name, wdg):
1161
1102
  wdg.write(name, self.workdir)
femagtools/fsl.py CHANGED
@@ -227,7 +227,7 @@ class Builder:
227
227
  # obsolete
228
228
  th_props = [' ']
229
229
  try:
230
- logger.info(model.magnet)
230
+ logger.debug(model.magnet)
231
231
  th_props = [f'rotor_density = {model["magnet"]["density"]}',
232
232
  f'rotor_thcond = {model["magnet"]["thcond"]}',
233
233
  f'rotor_thcap = {model["magnet"]["thcap"]}'
@@ -750,8 +750,11 @@ class Builder:
750
750
  sim['eccentricity'])
751
751
 
752
752
  if sim.get('calculationMode') == 'pm_sym_f_cur':
753
- if 'nload_ex_cur' in sim.keys(): # convert obsolete key
754
- sim['noload_ex_cur'] = sim.pop('nload_ex_cur')
753
+ if sim.get('nload_ex_cur', ''): # convert obsolete key
754
+ if isinstance(sim, dict):
755
+ sim['noload_ex_cur'] = sim.pop('nload_ex_cur')
756
+ else:
757
+ sim.noload_ex_cur = sim.get('nload_ex_cur')
755
758
  felosses = custom_fefunc + self.create_fe_losses(sim)
756
759
  fslcalc = (displ_stator_rotor
757
760
  + self.__render(sim, sim.get('calculationMode'))