femagtools 1.8.3__py3-none-any.whl → 1.8.4__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
@@ -10,20 +10,22 @@ 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
24
  journal = None
23
25
 
24
26
 
25
27
  def plot_geom(doit, plt, geom, title="Plot", areas=True):
26
- if not doit:
28
+ if not doit or not plt:
27
29
  return
28
30
 
29
31
  logger.info("Prepare Plot %s", title)
@@ -42,9 +44,121 @@ def plot_geom(doit, plt, geom, title="Plot", areas=True):
42
44
  fill_areas=areas)
43
45
 
44
46
 
47
+ class SymSearchProcess(SimpleProcess):
48
+ def __init__(self,
49
+ name=None,
50
+ queue=None,
51
+ machine=None,
52
+ plt=None, # plotter
53
+ kind="",
54
+ mindist=0.01,
55
+ symtol=0.0,
56
+ sympart=0,
57
+ is_inner=False,
58
+ is_outer=False,
59
+ show_plots=True,
60
+ debug_mode=False,
61
+ rows=1,
62
+ cols=1,
63
+ num=1,
64
+ no_processing=False):
65
+ SimpleProcess.__init__(self,
66
+ name=name,
67
+ no_processing=no_processing)
68
+ self.queue = queue
69
+ self.mach_in = machine
70
+ self.mach_out = None
71
+ self.plt = plt
72
+ self.kind = kind
73
+ self.mindist = mindist
74
+ self.symtol = symtol
75
+ self.sympart = sympart
76
+ self.is_inner = is_inner
77
+ self.is_outer = is_outer
78
+ self.show_plots = show_plots
79
+ self.debug_mode = debug_mode
80
+ self.rows = rows
81
+ self.cols = cols
82
+ self.num = num
83
+ pass
84
+
85
+ def run(self):
86
+ if not self.without_processing():
87
+ logger.info("Process is running")
88
+ self.plt = None
89
+ self.show_plots = False
90
+ else:
91
+ logger.info("without multiprocessing")
92
+
93
+ try:
94
+ self.mach_out = symmetry_search(
95
+ self.mach_in,
96
+ plt=self.plt,
97
+ kind=self.kind,
98
+ mindist=self.mindist,
99
+ symtol=self.symtol,
100
+ sympart=self.sympart,
101
+ is_inner=self.is_inner,
102
+ is_outer=self.is_outer,
103
+ show_plots=self.show_plots,
104
+ debug_mode=self.debug_mode,
105
+ rows=self.rows,
106
+ cols=self.cols,
107
+ num=self.num)
108
+ except Exception as e:
109
+ logger.warning("Exception in symmetry_search: %s", e)
110
+ if not self.mach_out:
111
+ logger.error("NO MACHINE AFTER PROCESS")
112
+ self.queue.put(self.mach_out)
113
+ if not self.without_processing():
114
+ logger.info("Process is finished")
115
+
116
+
117
+ class BuildInnerProcess(SimpleProcess):
118
+ def __init__(self,
119
+ name=None,
120
+ queue=None,
121
+ machine=None,
122
+ mindist=0.01,
123
+ plt=None, # plotter
124
+ EESM=False,
125
+ no_processing=False):
126
+ SimpleProcess.__init__(self,
127
+ name=name,
128
+ no_processing=no_processing)
129
+ self.queue = queue
130
+ self.mach_in = machine
131
+ self.mach_out = None
132
+ self.plt = plt
133
+ self.mindist = mindist
134
+ self.EESM = EESM
135
+ pass
136
+
137
+ def run(self):
138
+ if not self.without_processing():
139
+ logger.info("Process is running")
140
+ self.plt = None
141
+ else:
142
+ logger.info("without multiprocessing")
143
+
144
+ try:
145
+ self.mach_out = build_inner_machine(
146
+ self.mach_in,
147
+ mindist=self.mindist,
148
+ plt=self.plt,
149
+ EESM=self.EESM)
150
+ except Exception as e:
151
+ logger.warning("Exception in symmetry_search: %s", e)
152
+
153
+ self.queue.put(self.mach_out)
154
+ if not self.without_processing():
155
+ logger.info("Process is finished")
156
+
157
+
45
158
  def symmetry_search(machine,
46
- plt, # plotter
47
- kind,
159
+ plt=None, # plotter
160
+ kind="single",
161
+ mindist=0.01,
48
162
  symtol=0.0,
49
163
  sympart=0,
50
164
  is_inner=False,
@@ -56,11 +170,13 @@ def symmetry_search(machine,
56
170
  num=1):
57
171
  logger.info("*** Begin symmetry search for %s ***", kind)
58
172
 
59
- if is_inner:
60
- machine.set_inner()
61
- elif is_outer:
62
- machine.set_outer()
173
+ def return_machine(machine, kind):
174
+ machine.set_attributes(kind=kind, inner=is_inner, outer=is_outer)
175
+ machine.check_and_correct_geom(kind)
176
+ machine.delete_tiny_elements(mindist)
177
+ return machine
63
178
 
179
+ machine.set_attributes(kind=kind, inner=is_inner, outer=is_outer)
64
180
  machine.clear_cut_lines()
65
181
  if show_plots and debug_mode:
66
182
  plt.render_elements(machine.geom, Shape,
@@ -71,9 +187,8 @@ def symmetry_search(machine,
71
187
  logger.error("force symmetry failed")
72
188
  sys.exit(1)
73
189
  machine_ok = machine.get_forced_symmetry(sympart)
74
- machine_ok.set_kind(kind)
75
190
  logger.info("*** End of symmetry search for %s ***", kind)
76
- return machine_ok
191
+ return return_machine(machine_ok, kind)
77
192
 
78
193
  plot_geom(False, # for developer
79
194
  plt, machine.geom,
@@ -92,9 +207,8 @@ def symmetry_search(machine,
92
207
  rows=rows, cols=cols, num=num, show=False)
93
208
  machine_slice = machine.get_symmetry_slice()
94
209
  if machine_slice is None:
95
- machine.kind = kind
96
210
  logger.info(" - no slice extracted ?!?")
97
- return machine
211
+ return return_machine(machine, kind)
98
212
 
99
213
  plot_geom(False, # for developer
100
214
  plt, machine_slice.geom,
@@ -104,13 +218,11 @@ def symmetry_search(machine,
104
218
  machine_mirror = machine_slice.get_symmetry_mirror(no_third=True)
105
219
 
106
220
  if machine_mirror is not None:
107
- machine_mirror.set_kind(kind)
108
221
  logger.info("*** End of symmetry search for %s (symmetry and mirror) ***", kind)
109
- return machine_mirror
222
+ return return_machine(machine_mirror, kind)
110
223
 
111
- machine_slice.set_kind(kind)
112
224
  logger.info("*** End of symmetry search for %s (symmetry) ***", kind)
113
- return machine_slice
225
+ return return_machine(machine_slice, kind)
114
226
 
115
227
  # --- no symmetry slice found ---
116
228
  logger.info(" - {}: no symmetry axis found".format(kind))
@@ -129,6 +241,10 @@ def symmetry_search(machine,
129
241
  machine.rotate_to(0.0)
130
242
  machine.set_alfa_and_corners()
131
243
 
244
+ plot_geom(False, # for developer
245
+ plt, machine.geom,
246
+ title="Before Mirror ({})".format(kind))
247
+
132
248
  machine_mirror = machine.get_symmetry_mirror()
133
249
  machine_slice = machine
134
250
  machine_slice.set_alfa_and_corners()
@@ -146,6 +262,9 @@ def symmetry_search(machine,
146
262
  while machine_next_mirror is not None:
147
263
  logger.info(" - another mirror found")
148
264
  machine_mirror = machine_next_mirror
265
+ plot_geom(False, # for developer
266
+ plt, machine_mirror.geom,
267
+ title="Next Mirror ({})".format(kind))
149
268
  machine_next_mirror = machine_mirror.get_symmetry_mirror()
150
269
 
151
270
  machine_ok = machine_mirror
@@ -155,10 +274,8 @@ def symmetry_search(machine,
155
274
  machine_ok.rotate_to(0.0)
156
275
  machine_ok.set_alfa_and_corners()
157
276
 
158
- machine_ok.set_kind(kind)
159
-
160
277
  logger.info("*** End of symmetry search for %s ***", kind)
161
- return machine_ok
278
+ return return_machine(machine_ok, kind)
162
279
 
163
280
 
164
281
  def build_machine_rotor(machine, inner, mindist, plt, EESM=False, single=False):
@@ -313,6 +430,58 @@ def build_machine_stator(machine, inner, mindist, plt, EESM=False, single=False)
313
430
  return machine_temp
314
431
 
315
432
 
433
+ def build_inner_machine(machine,
434
+ mindist=0.01,
435
+ plt=None,
436
+ EESM=False):
437
+ logger.info("Begin of build_inner_machine")
438
+ machine.search_subregions(EESM)
439
+
440
+ if machine.geom.is_rotor(): # Inner mirrored rotor
441
+ machine = build_machine_rotor(machine,
442
+ True, # is inner
443
+ mindist,
444
+ plt,
445
+ EESM=EESM)
446
+
447
+ if machine.geom.is_stator() or machine.has_windings():
448
+ machine = build_machine_stator(machine,
449
+ True,
450
+ mindist,
451
+ plt,
452
+ EESM=EESM)
453
+
454
+ machine.search_critical_elements(mindist)
455
+ logger.info("End of build_inner_machine")
456
+ return machine
457
+
458
+
459
+ def build_outer_machine(machine,
460
+ mindist=0.01,
461
+ plt=None,
462
+ EESM=False):
463
+ logger.info("Begin of build_outer_machine")
464
+ machine.search_subregions(EESM)
465
+
466
+ if machine.geom.is_rotor(): # Outer mirrored rotor
467
+ machine = build_machine_rotor(machine,
468
+ False, # is outer
469
+ mindist,
470
+ plt,
471
+ EESM=EESM)
472
+
473
+ if machine.geom.is_stator() or machine.has_windings():
474
+ machine = build_machine_stator(machine,
475
+ False,
476
+ mindist,
477
+ plt,
478
+ EESM=EESM)
479
+
480
+ machine.search_critical_elements(mindist)
481
+ logger.info("End of build_outer_machine")
482
+ return machine
483
+
484
+
316
485
  def convert(dxfile,
317
486
  EESM=False,
318
487
  rtol=1e-04,
@@ -340,7 +509,8 @@ def convert(dxfile,
340
509
  write_id=False,
341
510
  full_model=False,
342
511
  debug_mode=False,
343
- write_journal=False):
512
+ write_journal=False,
513
+ no_processing=False):
344
514
  global journal
345
515
  layers = ()
346
516
  conv = {}
@@ -361,6 +531,7 @@ def convert(dxfile,
361
531
  basename,
362
532
  __version__)
363
533
  timer = Timer(start_it=True)
534
+ start_timer = Timer(start_it=True)
364
535
 
365
536
  journal = getJournal(name='converter_journal', aktiv=write_journal)
366
537
  journal.get_journal(input_file.name)
@@ -391,6 +562,8 @@ def convert(dxfile,
391
562
 
392
563
  if write_fsl_single:
393
564
  write_fsl = True
565
+ if small_plots:
566
+ show_plots = False
394
567
 
395
568
  try:
396
569
  if input_file.suffix in ['.fem', '.FEM']:
@@ -438,8 +611,6 @@ def convert(dxfile,
438
611
  logger.info("total elements %s", len(basegeom.g.edges()))
439
612
 
440
613
  p = PlotRenderer()
441
- if small_plots:
442
- show_plots = False
443
614
 
444
615
  if view_only:
445
616
  logger.info("View only")
@@ -466,6 +637,7 @@ def convert(dxfile,
466
637
 
467
638
  if not (machine_base.part > 0):
468
639
  # machine shape is unclear
640
+ logger.warn("machine shape is unclear")
469
641
  machine_base.set_center(0.0, 0.0)
470
642
  machine_base.set_radius(9999999)
471
643
 
@@ -556,72 +728,63 @@ def convert(dxfile,
556
728
  connect=True)
557
729
  machine_outer.set_outer()
558
730
 
731
+ start_timer.stop("-- first part in %0.4f seconds --", info=True)
732
+ process_timer = Timer(start_it=True)
559
733
  # 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)
734
+ inner_queue = multiprocessing.Queue()
735
+ inner_proc = SymSearchProcess(name="Inner", # for logger
736
+ queue=inner_queue,
737
+ machine=machine_inner,
738
+ plt=None, # plot
739
+ kind=inner_name,
740
+ is_inner=True,
741
+ mindist=mindist,
742
+ symtol=symtol,
743
+ show_plots=show_plots,
744
+ rows=3, # rows
745
+ cols=2, # columns
746
+ num=3, # start num
747
+ no_processing=no_processing)
748
+ inner_proc.start_task()
572
749
 
573
750
  # outer part
574
751
  machine_outer = symmetry_search(machine_outer,
575
- p, # plot
576
- outer_name,
752
+ plt=p, # plot
753
+ kind=outer_name,
577
754
  is_outer=True,
755
+ mindist=mindist,
578
756
  symtol=symtol,
579
757
  show_plots=show_plots,
580
758
  rows=3, # rows
581
759
  cols=2, # columns
582
760
  num=4) # start num
583
- machine_outer.check_and_correct_geom("Outer")
584
- machine_outer.delete_tiny_elements(mindist)
585
-
586
- machine_inner.sync_with_counterpart(machine_outer)
587
761
 
588
- machine_inner.search_subregions(EESM)
589
- machine_outer.search_subregions(EESM)
762
+ machine_inner = inner_queue.get()
763
+ inner_proc.wait()
764
+ process_timer.stop("-- symmetry search in %0.4f seconds --", info=True)
590
765
 
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
766
  machine_inner.sync_with_counterpart(machine_outer)
621
767
 
622
- machine_inner.search_critical_elements(mindist)
623
- machine_outer.search_critical_elements(mindist)
768
+ final_timer = Timer(start_it=True)
769
+ inner_queue = multiprocessing.Queue()
770
+ inner_proc = BuildInnerProcess(name="Inner", # for logger
771
+ queue=inner_queue,
772
+ machine=machine_inner,
773
+ mindist=mindist,
774
+ plt=p,
775
+ EESM=EESM,
776
+ no_processing=no_processing)
777
+ inner_proc.start_task()
778
+
779
+ machine_outer = build_outer_machine(machine_outer,
780
+ mindist,
781
+ p,
782
+ EESM=EESM)
783
+ machine_inner = inner_queue.get()
784
+ inner_proc.wait()
785
+ final_timer.stop("-- final part in %0.4f seconds --", info=True)
624
786
 
787
+ machine_inner.sync_with_counterpart(machine_outer)
625
788
  logger.info("***** END of work: %s *****", basename)
626
789
 
627
790
  if machine_inner.geom.is_rotor():
@@ -776,10 +939,11 @@ def convert(dxfile,
776
939
  outer = True
777
940
 
778
941
  machine = symmetry_search(machine,
779
- p, # plot
780
- name,
942
+ plt=p, # plot
943
+ kind=name,
781
944
  is_inner=inner,
782
945
  is_outer=outer,
946
+ mindist=mindist,
783
947
  symtol=symtol,
784
948
  sympart=sympart,
785
949
  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()