femagtools 1.8.3__py3-none-any.whl → 1.8.5__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.
@@ -10,20 +10,21 @@ 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, middle_angle
13
+ from femagtools.dxfsl.functions import Timer, SimpleProcess, middle_angle
14
14
  from femagtools.dxfsl.journal import Journal, getJournal
15
15
  from femagtools.dxfsl.area import TYPE_WINDINGS
16
+ from femagtools.dxfsl.areabuilder import disable_logging, enable_logging
16
17
  import logging
17
18
  import logging.config
18
19
  import numpy as np
19
20
  import sys
21
+ import multiprocessing
20
22
 
21
23
  logger = logging.getLogger(__name__)
22
- journal = None
23
24
 
24
25
 
25
26
  def plot_geom(doit, plt, geom, title="Plot", areas=True):
26
- if not doit:
27
+ if not doit or not plt:
27
28
  return
28
29
 
29
30
  logger.info("Prepare Plot %s", title)
@@ -42,9 +43,121 @@ def plot_geom(doit, plt, geom, title="Plot", areas=True):
42
43
  fill_areas=areas)
43
44
 
44
45
 
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
+
45
157
  def symmetry_search(machine,
46
- plt, # plotter
47
- kind,
158
+ plt=None, # plotter
159
+ kind="single",
160
+ mindist=0.01,
48
161
  symtol=0.0,
49
162
  sympart=0,
50
163
  is_inner=False,
@@ -56,11 +169,13 @@ def symmetry_search(machine,
56
169
  num=1):
57
170
  logger.info("*** Begin symmetry search for %s ***", kind)
58
171
 
59
- if is_inner:
60
- machine.set_inner()
61
- elif is_outer:
62
- machine.set_outer()
172
+ def return_machine(machine, kind):
173
+ machine.set_attributes(kind=kind, inner=is_inner, outer=is_outer)
174
+ machine.check_and_correct_geom(kind)
175
+ machine.delete_tiny_elements(mindist)
176
+ return machine
63
177
 
178
+ machine.set_attributes(kind=kind, inner=is_inner, outer=is_outer)
64
179
  machine.clear_cut_lines()
65
180
  if show_plots and debug_mode:
66
181
  plt.render_elements(machine.geom, Shape,
@@ -71,9 +186,8 @@ def symmetry_search(machine,
71
186
  logger.error("force symmetry failed")
72
187
  sys.exit(1)
73
188
  machine_ok = machine.get_forced_symmetry(sympart)
74
- machine_ok.set_kind(kind)
75
189
  logger.info("*** End of symmetry search for %s ***", kind)
76
- return machine_ok
190
+ return return_machine(machine_ok, kind)
77
191
 
78
192
  plot_geom(False, # for developer
79
193
  plt, machine.geom,
@@ -92,9 +206,8 @@ def symmetry_search(machine,
92
206
  rows=rows, cols=cols, num=num, show=False)
93
207
  machine_slice = machine.get_symmetry_slice()
94
208
  if machine_slice is None:
95
- machine.kind = kind
96
209
  logger.info(" - no slice extracted ?!?")
97
- return machine
210
+ return return_machine(machine, kind)
98
211
 
99
212
  plot_geom(False, # for developer
100
213
  plt, machine_slice.geom,
@@ -104,13 +217,11 @@ def symmetry_search(machine,
104
217
  machine_mirror = machine_slice.get_symmetry_mirror(no_third=True)
105
218
 
106
219
  if machine_mirror is not None:
107
- machine_mirror.set_kind(kind)
108
220
  logger.info("*** End of symmetry search for %s (symmetry and mirror) ***", kind)
109
- return machine_mirror
221
+ return return_machine(machine_mirror, kind)
110
222
 
111
- machine_slice.set_kind(kind)
112
223
  logger.info("*** End of symmetry search for %s (symmetry) ***", kind)
113
- return machine_slice
224
+ return return_machine(machine_slice, kind)
114
225
 
115
226
  # --- no symmetry slice found ---
116
227
  logger.info(" - {}: no symmetry axis found".format(kind))
@@ -129,6 +240,10 @@ def symmetry_search(machine,
129
240
  machine.rotate_to(0.0)
130
241
  machine.set_alfa_and_corners()
131
242
 
243
+ plot_geom(False, # for developer
244
+ plt, machine.geom,
245
+ title="Before Mirror ({})".format(kind))
246
+
132
247
  machine_mirror = machine.get_symmetry_mirror()
133
248
  machine_slice = machine
134
249
  machine_slice.set_alfa_and_corners()
@@ -146,6 +261,9 @@ def symmetry_search(machine,
146
261
  while machine_next_mirror is not None:
147
262
  logger.info(" - another mirror found")
148
263
  machine_mirror = machine_next_mirror
264
+ plot_geom(False, # for developer
265
+ plt, machine_mirror.geom,
266
+ title="Next Mirror ({})".format(kind))
149
267
  machine_next_mirror = machine_mirror.get_symmetry_mirror()
150
268
 
151
269
  machine_ok = machine_mirror
@@ -155,14 +273,11 @@ def symmetry_search(machine,
155
273
  machine_ok.rotate_to(0.0)
156
274
  machine_ok.set_alfa_and_corners()
157
275
 
158
- machine_ok.set_kind(kind)
159
-
160
276
  logger.info("*** End of symmetry search for %s ***", kind)
161
- return machine_ok
277
+ return return_machine(machine_ok, kind)
162
278
 
163
279
 
164
280
  def build_machine_rotor(machine, inner, mindist, plt, EESM=False, single=False):
165
- global journal
166
281
  logger.debug("Begin of build_machine_rotor")
167
282
 
168
283
  if machine.has_windings():
@@ -233,14 +348,12 @@ def build_machine_rotor(machine, inner, mindist, plt, EESM=False, single=False):
233
348
  title="Final Rotor")
234
349
 
235
350
  t = timer.stop("-- rotor created in %0.4f seconds --")
236
- journal.put('time_rotor_created', t)
237
351
 
238
352
  logger.debug("End of build_machine_rotor")
239
353
  return machine_temp
240
354
 
241
355
 
242
356
  def build_machine_stator(machine, inner, mindist, plt, EESM=False, single=False):
243
- global journal
244
357
  logger.debug("Begin of build_machine_stator")
245
358
  timer = Timer(start_it=True)
246
359
 
@@ -307,12 +420,63 @@ def build_machine_stator(machine, inner, mindist, plt, EESM=False, single=False)
307
420
  title="Final Stator")
308
421
 
309
422
  t = timer.stop("-- stator created in %0.4f seconds --")
310
- journal.put('time_stator_created', t)
311
423
 
312
424
  logger.debug("End of build_machine_stator")
313
425
  return machine_temp
314
426
 
315
427
 
428
+ def build_inner_machine(machine,
429
+ mindist=0.01,
430
+ plt=None,
431
+ EESM=False):
432
+ logger.info("Begin of build_inner_machine")
433
+ machine.search_subregions(EESM)
434
+
435
+ if machine.geom.is_rotor(): # Inner mirrored rotor
436
+ machine = build_machine_rotor(machine,
437
+ True, # is inner
438
+ mindist,
439
+ plt,
440
+ EESM=EESM)
441
+
442
+ if machine.geom.is_stator() or machine.has_windings():
443
+ machine = build_machine_stator(machine,
444
+ True,
445
+ mindist,
446
+ plt,
447
+ EESM=EESM)
448
+
449
+ machine.search_critical_elements(mindist)
450
+ logger.info("End of build_inner_machine")
451
+ return machine
452
+
453
+
454
+ def build_outer_machine(machine,
455
+ mindist=0.01,
456
+ plt=None,
457
+ EESM=False):
458
+ logger.info("Begin of build_outer_machine")
459
+ machine.search_subregions(EESM)
460
+
461
+ if machine.geom.is_rotor(): # Outer mirrored rotor
462
+ machine = build_machine_rotor(machine,
463
+ False, # is outer
464
+ mindist,
465
+ plt,
466
+ EESM=EESM)
467
+
468
+ if machine.geom.is_stator() or machine.has_windings():
469
+ machine = build_machine_stator(machine,
470
+ False,
471
+ mindist,
472
+ plt,
473
+ EESM=EESM)
474
+
475
+ machine.search_critical_elements(mindist)
476
+ logger.info("End of build_outer_machine")
477
+ return machine
478
+
479
+
316
480
  def convert(dxfile,
317
481
  EESM=False,
318
482
  rtol=1e-04,
@@ -340,7 +504,8 @@ def convert(dxfile,
340
504
  write_id=False,
341
505
  full_model=False,
342
506
  debug_mode=False,
343
- write_journal=False):
507
+ write_journal=False,
508
+ no_processing=False):
344
509
  global journal
345
510
  layers = ()
346
511
  conv = {}
@@ -361,6 +526,7 @@ def convert(dxfile,
361
526
  basename,
362
527
  __version__)
363
528
  timer = Timer(start_it=True)
529
+ start_timer = Timer(start_it=True)
364
530
 
365
531
  journal = getJournal(name='converter_journal', aktiv=write_journal)
366
532
  journal.get_journal(input_file.name)
@@ -391,6 +557,8 @@ def convert(dxfile,
391
557
 
392
558
  if write_fsl_single:
393
559
  write_fsl = True
560
+ if small_plots:
561
+ show_plots = False
394
562
 
395
563
  try:
396
564
  if input_file.suffix in ['.fem', '.FEM']:
@@ -438,8 +606,6 @@ def convert(dxfile,
438
606
  logger.info("total elements %s", len(basegeom.g.edges()))
439
607
 
440
608
  p = PlotRenderer()
441
- if small_plots:
442
- show_plots = False
443
609
 
444
610
  if view_only:
445
611
  logger.info("View only")
@@ -466,6 +632,7 @@ def convert(dxfile,
466
632
 
467
633
  if not (machine_base.part > 0):
468
634
  # machine shape is unclear
635
+ logger.warn("machine shape is unclear")
469
636
  machine_base.set_center(0.0, 0.0)
470
637
  machine_base.set_radius(9999999)
471
638
 
@@ -556,72 +723,63 @@ def convert(dxfile,
556
723
  connect=True)
557
724
  machine_outer.set_outer()
558
725
 
726
+ start_timer.stop("-- first part in %0.4f seconds --", info=True)
727
+ process_timer = Timer(start_it=True)
559
728
  # inner part
560
- machine_inner = symmetry_search(machine_inner,
561
- p, # plot
562
- inner_name,
563
- is_inner=True,
564
- symtol=symtol,
565
- show_plots=show_plots,
566
- rows=3, # rows
567
- cols=2, # columns
568
- num=3) # start num
569
- machine_inner.set_inner()
570
- machine_inner.check_and_correct_geom("Inner")
571
- machine_inner.delete_tiny_elements(mindist)
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()
572
744
 
573
745
  # outer part
574
746
  machine_outer = symmetry_search(machine_outer,
575
- p, # plot
576
- outer_name,
747
+ plt=p, # plot
748
+ kind=outer_name,
577
749
  is_outer=True,
750
+ mindist=mindist,
578
751
  symtol=symtol,
579
752
  show_plots=show_plots,
580
753
  rows=3, # rows
581
754
  cols=2, # columns
582
755
  num=4) # start num
583
- machine_outer.check_and_correct_geom("Outer")
584
- machine_outer.delete_tiny_elements(mindist)
585
756
 
586
- machine_inner.sync_with_counterpart(machine_outer)
757
+ machine_inner = inner_queue.get()
758
+ inner_proc.wait()
759
+ process_timer.stop("-- symmetry search in %0.4f seconds --", info=True)
587
760
 
588
- machine_inner.search_subregions(EESM)
589
- machine_outer.search_subregions(EESM)
590
-
591
- # Inner mirrored rotor
592
- if machine_inner.geom.is_rotor():
593
- machine_inner = build_machine_rotor(machine_inner,
594
- True, # is inner
595
- mindist,
596
- p,
597
- EESM=EESM)
598
-
599
- # Outer mirrored rotor
600
- if machine_outer.geom.is_rotor():
601
- machine_outer = build_machine_rotor(machine_outer,
602
- False, # is outer
603
- mindist,
604
- p,
605
- EESM=EESM)
606
-
607
- if machine_inner.geom.is_stator() or machine_inner.has_windings():
608
- machine_inner = build_machine_stator(machine_inner,
609
- True,
610
- mindist,
611
- p,
612
- EESM=EESM)
613
-
614
- if machine_outer.geom.is_stator() or machine_outer.has_windings():
615
- machine_outer = build_machine_stator(machine_outer,
616
- False,
617
- mindist,
618
- p,
619
- EESM=EESM)
620
761
  machine_inner.sync_with_counterpart(machine_outer)
621
762
 
622
- machine_inner.search_critical_elements(mindist)
623
- machine_outer.search_critical_elements(mindist)
763
+ 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()
773
+
774
+ machine_outer = build_outer_machine(machine_outer,
775
+ mindist,
776
+ p,
777
+ EESM=EESM)
778
+ machine_inner = inner_queue.get()
779
+ inner_proc.wait()
780
+ final_timer.stop("-- final part in %0.4f seconds --", info=True)
624
781
 
782
+ machine_inner.sync_with_counterpart(machine_outer)
625
783
  logger.info("***** END of work: %s *****", basename)
626
784
 
627
785
  if machine_inner.geom.is_rotor():
@@ -776,10 +934,11 @@ def convert(dxfile,
776
934
  outer = True
777
935
 
778
936
  machine = symmetry_search(machine,
779
- p, # plot
780
- name,
937
+ plt=p, # plot
938
+ kind=name,
781
939
  is_inner=inner,
782
940
  is_outer=outer,
941
+ mindist=mindist,
783
942
  symtol=symtol,
784
943
  sympart=sympart,
785
944
  show_plots=show_plots,
@@ -26,28 +26,18 @@ def agndst(da1, da2, Q, p, nodedist=1):
26
26
  """
27
27
  r = (da1 + da2)/4
28
28
  ag = abs(da1 - da2)/6
29
- num_nodes = [30, 48, 60, 96, 120, 144, 180, 240, 288, 336, 360,
30
- 432, 480]
31
- dagset = [2*np.pi/p/i for i in num_nodes]
32
- i = max(np.argmin(np.abs(np.array(dagset) - np.arctan2(ag, r))), 1)
33
- if p*num_nodes[i-1] % Q:
34
- lcm = np.lcm(Q, p)//p
35
- nmin, nmax = num_nodes[0]//lcm, num_nodes[-1]//lcm
36
- num_nodes = [i*lcm for i in range(nmin, nmax) if i*lcm%6==0]
37
- dagset = [2*np.pi/p/i for i in num_nodes]
38
- i = max(np.argmin(np.abs(np.array(dagset) - np.arctan2(ag, r))), 1)
39
- # nodedist 0.5, 2, 4, 6
40
- nd = min(round(nodedist), i)
41
- try:
42
- logger.info("Num nodes/p %d Num nodes/slot %g nodedist %g",
43
- num_nodes[i-1], p*num_nodes[i-1]/Q, nodedist)
44
- if nodedist > 1:
45
- return dagset[i-nd]*r
46
- if nodedist < 1 or i == 0:
47
- return dagset[i]*r
48
- except IndexError:
49
- pass
50
- return dagset[i-1]*r
29
+ lcm = np.lcm(Q, p)//p
30
+ taup = 2*np.pi*r/p
31
+ nmin, nmax = max(1, 18//lcm), 480//lcm
32
+ num_nodes = [i*lcm for i in range(nmin, nmax)
33
+ if i*lcm % 6 == 0 and i*lcm*p//Q % 2 == 0]
34
+ dagset = np.array([taup/i for i in num_nodes])
35
+ i = np.argmin(np.abs(dagset - ag*nodedist))
36
+ if i > 0 and dagset[i]*nodedist < ag:
37
+ i -= 1
38
+ logger.info("%d Num nodes/p %d Num nodes/slot %g nodedist %g",
39
+ i, num_nodes[i], p*num_nodes[i]/Q, nodedist)
40
+ return dagset[i]
51
41
 
52
42
 
53
43
  class FslRenderer(object):
@@ -629,9 +619,15 @@ class FslRenderer(object):
629
619
  'x2, y2 = pr2c(outer_da_start, 0.0)',
630
620
  'nc_line(r2, 0.0, x2, y2, 0.0)\n',
631
621
  'if m.tot_num_slot > m.num_sl_gen then',
622
+ ' if inner_da_end == nil then',
623
+ ' inner_da_end = inner_da_start',
624
+ ' end',
632
625
  ' x3, y3 = pr2c(inner_da_end, alfa)',
633
626
  ' x4, y4 = pr2c(r1, alfa)',
634
627
  ' nc_line(x3, y3, x4, y4, 0, 0)\n',
628
+ ' if outer_da_end == nil then',
629
+ ' outer_da_end = outer_da_start',
630
+ ' end',
635
631
  ' x3, y3 = pr2c(outer_da_end, alfa)',
636
632
  ' x4, y4 = pr2c(r2, alfa)',
637
633
  ' nc_line(x3, y3, x4, y4, 0, 0)',
@@ -12,6 +12,7 @@ import logging
12
12
  import numpy as np
13
13
  import copy
14
14
  import time
15
+ import multiprocessing
15
16
 
16
17
  logger = logging.getLogger('femagtools.functions')
17
18
 
@@ -76,8 +77,8 @@ def alpha_triangle(a, b, c):
76
77
  return rslt
77
78
 
78
79
 
79
- def alpha_angle(startangle, endangle):
80
- if less_equal(endangle, startangle):
80
+ def alpha_angle(startangle, endangle, rtol=1e-3, atol=1e-8):
81
+ if less_equal(endangle, startangle, rtol=rtol, atol=atol):
81
82
  endangle += 2.0*np.pi
82
83
  angle = endangle - startangle
83
84
  if less_equal(angle, 2.0*np.pi):
@@ -480,3 +481,24 @@ class Timer(object):
480
481
  else:
481
482
  logger.debug(fmt, sec)
482
483
  return sec
484
+
485
+
486
+ class SimpleProcess(multiprocessing.Process):
487
+ def __init__(self, name=None, no_processing=False):
488
+ super(SimpleProcess, self).__init__()
489
+ self._no_processing = no_processing
490
+ self.name = name
491
+
492
+ def without_processing(self):
493
+ return self._no_processing
494
+
495
+ def wait(self):
496
+ if not self._no_processing:
497
+ logger.debug("%s Waiting for Process", self.name)
498
+ self.join()
499
+
500
+ def start_task(self):
501
+ if self._no_processing:
502
+ self.run()
503
+ return
504
+ self.start()