femagtools 1.6.8__py3-none-any.whl → 1.7.1__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 (51) hide show
  1. femagtools/__init__.py +2 -2
  2. femagtools/bch.py +1 -1
  3. femagtools/dxfsl/area.py +343 -406
  4. femagtools/dxfsl/areabuilder.py +139 -12
  5. femagtools/dxfsl/conv.py +27 -9
  6. femagtools/dxfsl/converter.py +406 -127
  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 +1204 -893
  12. femagtools/dxfsl/journal.py +58 -22
  13. femagtools/dxfsl/machine.py +254 -75
  14. femagtools/dxfsl/plotrenderer.py +38 -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 +11 -7
  24. femagtools/machine/sizing.py +15 -12
  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.8.dist-info → femagtools-1.7.1.dist-info}/LICENSE +1 -0
  42. {femagtools-1.6.8.dist-info → femagtools-1.7.1.dist-info}/METADATA +7 -4
  43. {femagtools-1.6.8.dist-info → femagtools-1.7.1.dist-info}/RECORD +51 -50
  44. {femagtools-1.6.8.dist-info → femagtools-1.7.1.dist-info}/WHEEL +1 -1
  45. tests/engines/__init__.py +0 -20
  46. tests/geom/__init__.py +0 -20
  47. tests/moo/__init__.py +0 -20
  48. tests/test_model.py +8 -1
  49. tests/test_sizing.py +2 -2
  50. {femagtools-1.6.8.dist-info → femagtools-1.7.1.dist-info}/entry_points.txt +0 -0
  51. {femagtools-1.6.8.dist-info → femagtools-1.7.1.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
@@ -33,7 +33,7 @@ def disable_logging():
33
33
  logger.debug("Logging level %s disabled", original_log_level)
34
34
 
35
35
  # Set the log level to a higher level, e.g., WARNING or CRITICAL
36
- logging.disable(logging.CRITICAL)
36
+ logging.disable(logging.ERROR)
37
37
 
38
38
 
39
39
  def enable_logging():
@@ -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
@@ -339,7 +338,11 @@ class EdgeInfo(object):
339
338
  return True # two lines
340
339
 
341
340
  def arc_line_direction_lefthand(self, start_edge, line_edge, builder):
342
- logger.debug("begin of arc_line_direction_lefthand")
341
+ logger.info("begin of arc_line_direction_lefthand")
342
+ if not self.is_arc():
343
+ logger.critical("FATAL: unexpected %s at position %s", self.classname(), self.n1)
344
+ sys.exit(1)
345
+
343
346
  assert(self.is_arc())
344
347
  assert(line_edge.is_line())
345
348
  start_edge.log_edge(":::: start")
@@ -389,13 +392,16 @@ class AreaBuilder(object):
389
392
  rtol=1e-04,
390
393
  atol=1e-04,
391
394
  ndec=6):
395
+ assert(geom is not None)
392
396
  self.rtol = rtol
393
397
  self.atol = atol
394
398
  self.ndec = ndec
395
399
  self.geom = geom
396
400
  self.area_list = []
401
+ self.errors = 0
397
402
  self.journal = getJournal()
398
403
  self.nolog = nolog
404
+ self.num_edges = self.geom.number_of_edges()
399
405
 
400
406
  def __str__(self):
401
407
  return "rtol: {}\n".format(self.rtol) + \
@@ -410,7 +416,7 @@ class AreaBuilder(object):
410
416
 
411
417
  def append_new_area(self, area_list, elements):
412
418
  a = Area(elements, self.geom.center, 0.0)
413
- a.type = 0 # air
419
+ a.set_type(TYPE_AIR) # air
414
420
  area_list.append(a)
415
421
  return a
416
422
 
@@ -497,6 +503,7 @@ class AreaBuilder(object):
497
503
  logger.debug("<== %s", result['msg'])
498
504
  info_curr.set_all_tracked()
499
505
  result['ok'] = True
506
+ result['circle'] = True
500
507
  return result
501
508
 
502
509
  logger.debug("***** EDGE %s *****", 1)
@@ -521,9 +528,9 @@ class AreaBuilder(object):
521
528
  while not (nodes_are_equal(next_n1, start_n1) and
522
529
  nodes_are_equal(next_n2, start_n2)):
523
530
  c += 1
524
- if c > self.geom.num_edges * 2:
531
+ if c > self.num_edges * 2:
525
532
  logger.error("FATAL: *** over %s elements in area ? ***",
526
- self.geom.num_edges)
533
+ self.num_edges)
527
534
  sys.exit(1)
528
535
 
529
536
  area.append(info_next.element)
@@ -619,7 +626,7 @@ class AreaBuilder(object):
619
626
  logger.debug("end of next_edge_lefthand_side")
620
627
  return nbr1
621
628
 
622
- def create_inner_corner_auxiliary_areas(self):
629
+ def create_inner_corner_auxiliary_areas(self, startangle, endangle):
623
630
  logger.debug("begin of create_inner_corner_auxiliary_areas")
624
631
  if not self.geom.is_inner:
625
632
  logger.debug("end of create_inner_corner_auxiliary_areas: not inner")
@@ -627,8 +634,17 @@ class AreaBuilder(object):
627
634
 
628
635
  self.set_edge_attributes()
629
636
 
637
+ start_nodes = [n for n in self.geom.angle_nodes(
638
+ self.geom.center,
639
+ startangle, 1e-3, 1e-3)]
640
+ for n in start_nodes:
641
+ nbrs = self.geom.get_neighbors(n)
642
+ logger.debug("start node %s has %s neighbors", n, len(nbrs))
643
+ logger.debug("corner nodes: %s", self.geom.start_corners)
644
+ logger.debug("end nodes: %s", self.geom.end_corners)
630
645
  start_cp, start_exists = self.geom.get_start_airgap_corner()
631
646
  end_cp, end_exists = self.geom.get_end_airgap_corner()
647
+
632
648
  if start_exists and end_exists:
633
649
  logger.debug("end of create_inner_corner_auxiliary_areas: no aktion")
634
650
  return
@@ -667,8 +683,9 @@ class AreaBuilder(object):
667
683
  n,
668
684
  color='red',
669
685
  linestyle='dotted')
670
- self.geom.add_edge(cp, start_cp, start_line)
671
- result = self.get_new_area(start_cp, n)
686
+ start_node = self.geom.get_node(start_cp)
687
+ self.geom.add_edge(cp, start_node, start_line)
688
+ result = self.get_new_area(start_node, n)
672
689
  if result['ok']:
673
690
  self.append_new_area(self.geom.area_list,
674
691
  result['area'])
@@ -698,8 +715,9 @@ class AreaBuilder(object):
698
715
  self.geom.add_line(end_cp, n,
699
716
  color='red',
700
717
  linestyle='dotted')
701
- self.geom.add_edge(cp, end_cp, end_line)
702
- result = self.get_new_area(n, end_cp)
718
+ end_node = self.geom.get_node(end_cp)
719
+ self.geom.add_edge(cp, end_node, end_line)
720
+ result = self.get_new_area(n, end_node)
703
721
  if result['ok']:
704
722
  self.append_new_area(self.geom.area_list,
705
723
  result['area'])
@@ -783,3 +801,112 @@ class AreaBuilder(object):
783
801
  logger.debug("end of get_inner_airgap_line #%s", len(nodes))
784
802
  return nodes, elements
785
803
 
804
+ def create_one_area_group(self, areas):
805
+ logger.debug("begin of create_one_area_group")
806
+ assert(len(self.area_list) == 0)
807
+
808
+ self.set_edge_attributes()
809
+ if not self.build_group_area(areas):
810
+ logger.warning("Creation of an areagroup failed")
811
+ return True
812
+ return False
813
+
814
+ def create_area_groups(self, list_of_areas):
815
+ logger.debug("begin of create_area_groups")
816
+ assert(len(self.area_list) == 0)
817
+
818
+ area_id_list = [a.id for a in list_of_areas]
819
+ timer = Timer(start_it=True)
820
+ # ---
821
+ def delete_id(id):
822
+ try:
823
+ i = area_id_list.index(id)
824
+ except ValueError:
825
+ return True
826
+ area_id_list[i] = 0
827
+ # ---
828
+
829
+ group_list = {}
830
+ for area in list_of_areas:
831
+ if not area.id in area_id_list:
832
+ continue
833
+
834
+ areas = [area]
835
+ delete_id(area.id)
836
+ for a in list_of_areas:
837
+ if area.id == a.id:
838
+ continue
839
+ if not a.id in area_id_list:
840
+ continue
841
+ if area.is_in_touch_with_area(self.geom, a):
842
+ areas.append(a)
843
+ delete_id(a.id)
844
+
845
+ group_list[area.id] = areas
846
+
847
+ group_keys = [int(x) for x in group_list.keys()]
848
+ logger.debug("=== Area Group List ===")
849
+ self.set_edge_attributes()
850
+ errors = 0
851
+ disable_logging()
852
+ for k in group_keys:
853
+ if not self.build_group_area(group_list[k]):
854
+ logger.warning("Creation of an areagroup failed")
855
+ errors += 1
856
+ enable_logging()
857
+
858
+ t = timer.stop("areagroups created in %0.4f seconds")
859
+ logger.debug("end of create_area_groups: %s groups created",
860
+ len(self.area_list))
861
+ return errors > 0
862
+
863
+ def build_group_area(self, area_list):
864
+ id_list = [a.id for a in area_list]
865
+ logger.debug("Area Group: %s", id_list)
866
+
867
+ max_x = 0
868
+ area = None
869
+ for a in area_list:
870
+ if a.max_x > max_x:
871
+ max_x = a.max_x
872
+ area = a
873
+
874
+ x0, y0 = -9999.0, 0.0
875
+ for x, y in area.list_of_nodes():
876
+ if x > x0:
877
+ x0 = x
878
+ y0 = y
879
+
880
+ node0 = (x0, y0)
881
+ if not self.geom.g.has_node(node0):
882
+ node0 = self.geom.find_the_node(node0)
883
+ x0, y0 = node0
884
+
885
+ nbrs = self.geom.get_neighbors(node0)
886
+ logger.debug("Neighbors of %s", node0)
887
+
888
+ alpha0 = alpha_line(node0, (x, -9999.0))
889
+ angle0 = np.pi * 2.0
890
+ for n in nbrs:
891
+ logger.debug("** nbr: %s", n)
892
+ alpha1 = alpha_line(node0, n)
893
+ angle1 = alpha_angle(alpha1, alpha0)
894
+ logger.debug("** nbr=%s, alpha=%s, angle=%s", n, alpha1, angle1)
895
+ logger.debug("** if %s < %s then", angle1, angle0)
896
+ if angle1 < angle0:
897
+ node1 = n
898
+ angle0 = angle1
899
+
900
+ logger.debug("** Start with nodes %s ==> %s", node0, node1)
901
+ rslt = self.get_new_area(node0, node1)
902
+ if rslt['ok'] and rslt.get('circle', False):
903
+ rslt['ok'] = False
904
+ rslt['reverse'] = True
905
+
906
+ logger.debug("** Result: ok=%s, reverse=%s", rslt['ok'], rslt['reverse'])
907
+ if not rslt['ok'] and rslt['reverse']:
908
+ # new areagroup
909
+ a = self.append_new_area(self.area_list, rslt['area'])
910
+ a.areas_of_group = area_list
911
+ return True
912
+ 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