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.
- femagtools/__init__.py +2 -2
- femagtools/bch.py +1 -1
- femagtools/dxfsl/area.py +343 -406
- femagtools/dxfsl/areabuilder.py +139 -12
- femagtools/dxfsl/conv.py +27 -9
- femagtools/dxfsl/converter.py +406 -127
- femagtools/dxfsl/corner.py +3 -0
- femagtools/dxfsl/femparser.py +1 -1
- femagtools/dxfsl/fslrenderer.py +290 -246
- femagtools/dxfsl/functions.py +4 -2
- femagtools/dxfsl/geom.py +1204 -893
- femagtools/dxfsl/journal.py +58 -22
- femagtools/dxfsl/machine.py +254 -75
- femagtools/dxfsl/plotrenderer.py +38 -3
- femagtools/dxfsl/shape.py +380 -103
- femagtools/dxfsl/symmetry.py +679 -110
- femagtools/femag.py +27 -2
- femagtools/forcedens.py +65 -40
- femagtools/fsl.py +71 -28
- femagtools/losscoeffs.py +46 -0
- femagtools/machine/effloss.py +8 -1
- femagtools/machine/im.py +3 -1
- femagtools/machine/pm.py +11 -7
- femagtools/machine/sizing.py +15 -12
- femagtools/machine/sm.py +114 -33
- femagtools/machine/utils.py +38 -34
- femagtools/model.py +12 -2
- femagtools/moo/population.py +1 -1
- femagtools/parstudy.py +17 -1
- femagtools/plot/__init__.py +1 -1
- femagtools/plot/char.py +24 -7
- femagtools/plot/forcedens.py +56 -29
- femagtools/plot/mcv.py +4 -1
- femagtools/plot/phasor.py +6 -1
- femagtools/poc.py +17 -10
- femagtools/templates/cogg_calc.mako +7 -1
- femagtools/templates/displ_stator_rotor.mako +33 -0
- femagtools/templates/fieldcalc.mako +10 -16
- femagtools/templates/pm_sym_f_cur.mako +1 -1
- femagtools/tks.py +3 -9
- {femagtools-1.6.8.dist-info → femagtools-1.7.1.dist-info}/LICENSE +1 -0
- {femagtools-1.6.8.dist-info → femagtools-1.7.1.dist-info}/METADATA +7 -4
- {femagtools-1.6.8.dist-info → femagtools-1.7.1.dist-info}/RECORD +51 -50
- {femagtools-1.6.8.dist-info → femagtools-1.7.1.dist-info}/WHEEL +1 -1
- tests/engines/__init__.py +0 -20
- tests/geom/__init__.py +0 -20
- tests/moo/__init__.py +0 -20
- tests/test_model.py +8 -1
- tests/test_sizing.py +2 -2
- {femagtools-1.6.8.dist-info → femagtools-1.7.1.dist-info}/entry_points.txt +0 -0
- {femagtools-1.6.8.dist-info → femagtools-1.7.1.dist-info}/top_level.txt +0 -0
femagtools/dxfsl/areabuilder.py
CHANGED
@@ -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.
|
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.
|
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.
|
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.
|
531
|
+
if c > self.num_edges * 2:
|
525
532
|
logger.error("FATAL: *** over %s elements in area ? ***",
|
526
|
-
self.
|
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.
|
671
|
-
|
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.
|
702
|
-
|
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-
|
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=
|
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('
|
126
|
-
help='print information in
|
127
|
-
dest='
|
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
|
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
|