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.
- femagtools/__init__.py +2 -2
- femagtools/bch.py +1 -1
- femagtools/dxfsl/area.py +334 -332
- femagtools/dxfsl/areabuilder.py +131 -10
- femagtools/dxfsl/conv.py +27 -9
- femagtools/dxfsl/converter.py +390 -125
- 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 +1120 -886
- femagtools/dxfsl/journal.py +53 -22
- femagtools/dxfsl/machine.py +250 -74
- femagtools/dxfsl/plotrenderer.py +34 -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 +12 -11
- femagtools/machine/sizing.py +14 -11
- 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.7.dist-info → femagtools-1.7.0.dist-info}/LICENSE +1 -0
- {femagtools-1.6.7.dist-info → femagtools-1.7.0.dist-info}/METADATA +7 -4
- {femagtools-1.6.7.dist-info → femagtools-1.7.0.dist-info}/RECORD +50 -49
- tests/engines/__init__.py +0 -20
- tests/geom/__init__.py +0 -20
- tests/moo/__init__.py +0 -20
- tests/test_model.py +8 -1
- {femagtools-1.6.7.dist-info → femagtools-1.7.0.dist-info}/WHEEL +0 -0
- {femagtools-1.6.7.dist-info → femagtools-1.7.0.dist-info}/entry_points.txt +0 -0
- {femagtools-1.6.7.dist-info → femagtools-1.7.0.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
|
@@ -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.
|
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.
|
527
|
+
if c > self.num_edges * 2:
|
525
528
|
logger.error("FATAL: *** over %s elements in area ? ***",
|
526
|
-
self.
|
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.
|
671
|
-
|
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.
|
702
|
-
|
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-
|
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
|