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

Sign up to get free protection for your applications and to get access to all the features.
@@ -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()