femagtools 1.6.7__py3-none-any.whl → 1.7.0__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.
Files changed (50) hide show
  1. femagtools/__init__.py +2 -2
  2. femagtools/bch.py +1 -1
  3. femagtools/dxfsl/area.py +334 -332
  4. femagtools/dxfsl/areabuilder.py +131 -10
  5. femagtools/dxfsl/conv.py +27 -9
  6. femagtools/dxfsl/converter.py +390 -125
  7. femagtools/dxfsl/corner.py +3 -0
  8. femagtools/dxfsl/femparser.py +1 -1
  9. femagtools/dxfsl/fslrenderer.py +290 -246
  10. femagtools/dxfsl/functions.py +4 -2
  11. femagtools/dxfsl/geom.py +1120 -886
  12. femagtools/dxfsl/journal.py +53 -22
  13. femagtools/dxfsl/machine.py +250 -74
  14. femagtools/dxfsl/plotrenderer.py +34 -3
  15. femagtools/dxfsl/shape.py +380 -103
  16. femagtools/dxfsl/symmetry.py +679 -110
  17. femagtools/femag.py +27 -2
  18. femagtools/forcedens.py +65 -40
  19. femagtools/fsl.py +71 -28
  20. femagtools/losscoeffs.py +46 -0
  21. femagtools/machine/effloss.py +8 -1
  22. femagtools/machine/im.py +3 -1
  23. femagtools/machine/pm.py +12 -11
  24. femagtools/machine/sizing.py +14 -11
  25. femagtools/machine/sm.py +114 -33
  26. femagtools/machine/utils.py +38 -34
  27. femagtools/model.py +12 -2
  28. femagtools/moo/population.py +1 -1
  29. femagtools/parstudy.py +17 -1
  30. femagtools/plot/__init__.py +1 -1
  31. femagtools/plot/char.py +24 -7
  32. femagtools/plot/forcedens.py +56 -29
  33. femagtools/plot/mcv.py +4 -1
  34. femagtools/plot/phasor.py +6 -1
  35. femagtools/poc.py +17 -10
  36. femagtools/templates/cogg_calc.mako +7 -1
  37. femagtools/templates/displ_stator_rotor.mako +33 -0
  38. femagtools/templates/fieldcalc.mako +10 -16
  39. femagtools/templates/pm_sym_f_cur.mako +1 -1
  40. femagtools/tks.py +3 -9
  41. {femagtools-1.6.7.dist-info → femagtools-1.7.0.dist-info}/LICENSE +1 -0
  42. {femagtools-1.6.7.dist-info → femagtools-1.7.0.dist-info}/METADATA +7 -4
  43. {femagtools-1.6.7.dist-info → femagtools-1.7.0.dist-info}/RECORD +50 -49
  44. tests/engines/__init__.py +0 -20
  45. tests/geom/__init__.py +0 -20
  46. tests/moo/__init__.py +0 -20
  47. tests/test_model.py +8 -1
  48. {femagtools-1.6.7.dist-info → femagtools-1.7.0.dist-info}/WHEEL +0 -0
  49. {femagtools-1.6.7.dist-info → femagtools-1.7.0.dist-info}/entry_points.txt +0 -0
  50. {femagtools-1.6.7.dist-info → femagtools-1.7.0.dist-info}/top_level.txt +0 -0
@@ -12,7 +12,7 @@ import logging
12
12
  import sys
13
13
  from femagtools.dxfsl.shape import Element, Shape, Circle, Arc, Line
14
14
  from femagtools.dxfsl.shape import is_Circle, is_Arc, is_Line
15
- from femagtools.dxfsl.area import Area
15
+ from femagtools.dxfsl.area import Area, TYPE_AIR
16
16
  from femagtools.dxfsl.functions import points_are_close, nodes_are_equal, distance
17
17
  from femagtools.dxfsl.functions import normalise_angle, positive_angle, point
18
18
  from femagtools.dxfsl.functions import alpha_line, alpha_points, alpha_angle
@@ -80,7 +80,6 @@ class EdgeInfo(object):
80
80
  self.x = x
81
81
  self.tracked = edge_data.get(x, False)
82
82
  self.alpha = 0.0
83
- self.errors = 0
84
83
  self.startangle = None
85
84
  self.angle = None
86
85
  self.name = None
@@ -389,13 +388,16 @@ class AreaBuilder(object):
389
388
  rtol=1e-04,
390
389
  atol=1e-04,
391
390
  ndec=6):
391
+ assert(geom is not None)
392
392
  self.rtol = rtol
393
393
  self.atol = atol
394
394
  self.ndec = ndec
395
395
  self.geom = geom
396
396
  self.area_list = []
397
+ self.errors = 0
397
398
  self.journal = getJournal()
398
399
  self.nolog = nolog
400
+ self.num_edges = self.geom.number_of_edges()
399
401
 
400
402
  def __str__(self):
401
403
  return "rtol: {}\n".format(self.rtol) + \
@@ -410,7 +412,7 @@ class AreaBuilder(object):
410
412
 
411
413
  def append_new_area(self, area_list, elements):
412
414
  a = Area(elements, self.geom.center, 0.0)
413
- a.type = 0 # air
415
+ a.set_type(TYPE_AIR) # air
414
416
  area_list.append(a)
415
417
  return a
416
418
 
@@ -497,6 +499,7 @@ class AreaBuilder(object):
497
499
  logger.debug("<== %s", result['msg'])
498
500
  info_curr.set_all_tracked()
499
501
  result['ok'] = True
502
+ result['circle'] = True
500
503
  return result
501
504
 
502
505
  logger.debug("***** EDGE %s *****", 1)
@@ -521,9 +524,9 @@ class AreaBuilder(object):
521
524
  while not (nodes_are_equal(next_n1, start_n1) and
522
525
  nodes_are_equal(next_n2, start_n2)):
523
526
  c += 1
524
- if c > self.geom.num_edges * 2:
527
+ if c > self.num_edges * 2:
525
528
  logger.error("FATAL: *** over %s elements in area ? ***",
526
- self.geom.num_edges)
529
+ self.num_edges)
527
530
  sys.exit(1)
528
531
 
529
532
  area.append(info_next.element)
@@ -619,7 +622,7 @@ class AreaBuilder(object):
619
622
  logger.debug("end of next_edge_lefthand_side")
620
623
  return nbr1
621
624
 
622
- def create_inner_corner_auxiliary_areas(self):
625
+ def create_inner_corner_auxiliary_areas(self, startangle, endangle):
623
626
  logger.debug("begin of create_inner_corner_auxiliary_areas")
624
627
  if not self.geom.is_inner:
625
628
  logger.debug("end of create_inner_corner_auxiliary_areas: not inner")
@@ -627,8 +630,17 @@ class AreaBuilder(object):
627
630
 
628
631
  self.set_edge_attributes()
629
632
 
633
+ start_nodes = [n for n in self.geom.angle_nodes(
634
+ self.geom.center,
635
+ startangle, 1e-3, 1e-3)]
636
+ for n in start_nodes:
637
+ nbrs = self.geom.get_neighbors(n)
638
+ logger.debug("start node %s has %s neighbors", n, len(nbrs))
639
+ logger.debug("corner nodes: %s", self.geom.start_corners)
640
+ logger.debug("end nodes: %s", self.geom.end_corners)
630
641
  start_cp, start_exists = self.geom.get_start_airgap_corner()
631
642
  end_cp, end_exists = self.geom.get_end_airgap_corner()
643
+
632
644
  if start_exists and end_exists:
633
645
  logger.debug("end of create_inner_corner_auxiliary_areas: no aktion")
634
646
  return
@@ -667,8 +679,9 @@ class AreaBuilder(object):
667
679
  n,
668
680
  color='red',
669
681
  linestyle='dotted')
670
- self.geom.add_edge(cp, start_cp, start_line)
671
- result = self.get_new_area(start_cp, n)
682
+ start_node = self.geom.get_node(start_cp)
683
+ self.geom.add_edge(cp, start_node, start_line)
684
+ result = self.get_new_area(start_node, n)
672
685
  if result['ok']:
673
686
  self.append_new_area(self.geom.area_list,
674
687
  result['area'])
@@ -698,8 +711,9 @@ class AreaBuilder(object):
698
711
  self.geom.add_line(end_cp, n,
699
712
  color='red',
700
713
  linestyle='dotted')
701
- self.geom.add_edge(cp, end_cp, end_line)
702
- result = self.get_new_area(n, end_cp)
714
+ end_node = self.geom.get_node(end_cp)
715
+ self.geom.add_edge(cp, end_node, end_line)
716
+ result = self.get_new_area(n, end_node)
703
717
  if result['ok']:
704
718
  self.append_new_area(self.geom.area_list,
705
719
  result['area'])
@@ -783,3 +797,110 @@ class AreaBuilder(object):
783
797
  logger.debug("end of get_inner_airgap_line #%s", len(nodes))
784
798
  return nodes, elements
785
799
 
800
+ def create_one_area_group(self, areas):
801
+ logger.debug("begin of create_one_area_group")
802
+ assert(len(self.area_list) == 0)
803
+
804
+ self.set_edge_attributes()
805
+ if not self.build_group_area(areas):
806
+ logger.warning("Creation of an areagroup failed")
807
+ return True
808
+ return False
809
+
810
+ def create_area_groups(self, list_of_areas):
811
+ logger.debug("begin of create_area_groups")
812
+ assert(len(self.area_list) == 0)
813
+
814
+ area_id_list = [a.id for a in list_of_areas]
815
+ timer = Timer(start_it=True)
816
+ # ---
817
+ def delete_id(id):
818
+ try:
819
+ i = area_id_list.index(id)
820
+ except ValueError:
821
+ return True
822
+ area_id_list[i] = 0
823
+ # ---
824
+
825
+ group_list = {}
826
+ for area in list_of_areas:
827
+ if not area.id in area_id_list:
828
+ continue
829
+
830
+ areas = [area]
831
+ delete_id(area.id)
832
+ for a in list_of_areas:
833
+ if area.id == a.id:
834
+ continue
835
+ if not a.id in area_id_list:
836
+ continue
837
+ if area.is_in_touch_with_area(self.geom, a):
838
+ areas.append(a)
839
+ delete_id(a.id)
840
+
841
+ group_list[area.id] = areas
842
+
843
+ group_keys = [int(x) for x in group_list.keys()]
844
+ logger.debug("=== Area Group List ===")
845
+ self.set_edge_attributes()
846
+ errors = 0
847
+ for k in group_keys:
848
+ if not self.build_group_area(group_list[k]):
849
+ logger.warning("Creation of an areagroup failed")
850
+ errors += 1
851
+
852
+ t = timer.stop("areagroups created in %0.4f seconds")
853
+ logger.debug("end of create_area_groups: %s groups created",
854
+ len(self.area_list))
855
+ return errors > 0
856
+
857
+ def build_group_area(self, area_list):
858
+ id_list = [a.id for a in area_list]
859
+ logger.debug("Area Group: %s", id_list)
860
+
861
+ max_x = 0
862
+ area = None
863
+ for a in area_list:
864
+ if a.max_x > max_x:
865
+ max_x = a.max_x
866
+ area = a
867
+
868
+ x0, y0 = -9999.0, 0.0
869
+ for x, y in area.list_of_nodes():
870
+ if x > x0:
871
+ x0 = x
872
+ y0 = y
873
+
874
+ node0 = (x0, y0)
875
+ if not self.geom.g.has_node(node0):
876
+ node0 = self.geom.find_the_node(node0)
877
+ x0, y0 = node0
878
+
879
+ nbrs = self.geom.get_neighbors(node0)
880
+ logger.debug("Neighbors of %s", node0)
881
+
882
+ alpha0 = alpha_line(node0, (x, -9999.0))
883
+ angle0 = np.pi * 2.0
884
+ for n in nbrs:
885
+ logger.debug("** nbr: %s", n)
886
+ alpha1 = alpha_line(node0, n)
887
+ angle1 = alpha_angle(alpha1, alpha0)
888
+ logger.debug("** nbr=%s, alpha=%s, angle=%s", n, alpha1, angle1)
889
+ logger.debug("** if %s < %s then", angle1, angle0)
890
+ if angle1 < angle0:
891
+ node1 = n
892
+ angle0 = angle1
893
+
894
+ logger.debug("** Start with nodes %s ==> %s", node0, node1)
895
+ rslt = self.get_new_area(node0, node1)
896
+ if rslt['ok'] and rslt.get('circle', False):
897
+ rslt['ok'] = False
898
+ rslt['reverse'] = True
899
+
900
+ logger.debug("** Result: ok=%s, reverse=%s", rslt['ok'], rslt['reverse'])
901
+ if not rslt['ok'] and rslt['reverse']:
902
+ # new areagroup
903
+ a = self.append_new_area(self.area_list, rslt['area'])
904
+ a.areas_of_group = area_list
905
+ return True
906
+ return False
femagtools/dxfsl/conv.py CHANGED
@@ -9,14 +9,18 @@ import os
9
9
  import io
10
10
  import femagtools
11
11
  from femagtools.dxfsl.converter import convert
12
+ from femagtools.dxfsl.journal import Journal, getJournal
12
13
  import argparse
13
14
  import logging
14
15
  import logging.config
15
16
 
16
17
  logger = logging.getLogger(__name__)
18
+ journal = None
17
19
 
18
20
 
19
21
  def main():
22
+ global journal
23
+
20
24
  argparser = argparse.ArgumentParser(
21
25
  description='Process DXF file and create a plot or FSL file.')
22
26
  argparser.add_argument('dxfile',
@@ -66,12 +70,12 @@ def main():
66
70
  help='relative tolerance (pickdist)',
67
71
  dest='rtol',
68
72
  type=float,
69
- default=1e-03)
73
+ default=1e-04)
70
74
  argparser.add_argument('--atol',
71
75
  help='absolut tolerance (pickdist)',
72
76
  dest='atol',
73
77
  type=float,
74
- default=0.005)
78
+ default=1e-03)
75
79
  argparser.add_argument('--da',
76
80
  help='distance airgap',
77
81
  dest='da',
@@ -90,6 +94,10 @@ def main():
90
94
  help='show plots',
91
95
  dest='show_plots',
92
96
  action="store_true")
97
+ argparser.add_argument('--small',
98
+ help='show rotor/stator plots only',
99
+ dest='small_plots',
100
+ action="store_true")
93
101
  argparser.add_argument('--areas',
94
102
  help='show all areas',
95
103
  dest='show_areas',
@@ -122,9 +130,9 @@ def main():
122
130
  help='print information in logfile and set --debug',
123
131
  dest='debug',
124
132
  action="store_true")
125
- argparser.add_argument('--logfile',
126
- help='print information in logfile',
127
- dest='logfile',
133
+ argparser.add_argument('-j',
134
+ help='print information in journal file',
135
+ dest='journal',
128
136
  action="store_true")
129
137
  argparser.add_argument('--version',
130
138
  help='show version of some packages',
@@ -134,6 +142,10 @@ def main():
134
142
  help='print debug information in logfile',
135
143
  dest='debugger',
136
144
  action="store_true")
145
+ argparser.add_argument('--full_model',
146
+ help='create full model (fsl only)',
147
+ dest='full_model',
148
+ action="store_true")
137
149
 
138
150
  args = argparser.parse_args()
139
151
 
@@ -141,7 +153,7 @@ def main():
141
153
  loglevel = logging.INFO
142
154
  if args.debug:
143
155
  loglevel = logging.DEBUG
144
- if args.debug or args.logfile:
156
+ if args.debug:
145
157
  logfilename = 'debugger.log'
146
158
  print("see log-messages in {}".format(logfilename))
147
159
 
@@ -165,6 +177,8 @@ def main():
165
177
  logger.info("Python: %s", sys.version)
166
178
  sys.exit(0)
167
179
 
180
+ journal = getJournal(name='converter_journal', aktiv=args.journal)
181
+
168
182
  if args.airgap > 0.0:
169
183
  if args.airgap2 > 0.0:
170
184
  logger.info("Airgap is set from {} to {}"
@@ -218,17 +232,21 @@ def main():
218
232
  view_korr=args.view_korr,
219
233
  show_plots=args.show_plots,
220
234
  show_areas=args.show_areas,
235
+ small_plots=args.small_plots,
221
236
  write_fsl=args.write_fsl,
222
237
  write_png=args.write_png,
223
238
  write_id=args.write_id,
224
- debug_mode=args.debugger)
225
-
239
+ debug_mode=args.debugger,
240
+ full_model=args.full_model)
241
+ keys = ('tot_num_slot', 'num_sl_gen', 'num_poles', 'nodedist',
242
+ 'dy1', 'da1', 'da2', 'dy2', 'agndst', 'name')
243
+ logger.info("%s", {k: res[k] for k in keys if k in res})
226
244
  if args.write_fsl:
227
245
  if res is not None:
228
246
  basename = os.path.basename(args.dxfile).split('.')[0]
229
247
  with io.open(basename + '.fsl', 'w', encoding='utf-8') as f:
230
248
  f.write('\n'.join(res['fsl']))
231
-
249
+ journal.write_journal()
232
250
 
233
251
  if __name__ == "__main__":
234
252
  loglevel = logging.INFO