femagtools 1.6.4__py3-none-any.whl → 1.6.6__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 CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  """
4
4
  __title__ = 'femagtools'
5
- __version__ = '1.6.4'
5
+ __version__ = '1.6.6'
6
6
  __author__ = 'Ronald Tanner'
7
7
  __license__ = 'BSD'
8
8
  __copyright__ = 'Copyright 2016-2022 SEMAFOR Informatik & Energie AG'
femagtools/dxfsl/area.py CHANGED
@@ -45,6 +45,7 @@ class Area(object):
45
45
  self.mag_rectangle = False
46
46
  self.min_dist = 99999.0
47
47
  self.max_dist = 0.0
48
+ self.minmax_xy = [0,0,0,0]
48
49
  self.height = 0.0
49
50
  self.alpha = 0.0
50
51
  self.count = 1
@@ -269,6 +270,7 @@ class Area(object):
269
270
  if not self.area:
270
271
  return
271
272
 
273
+ self.minmax_xy = self.minmax()
272
274
  s = self.area[0]
273
275
  mm_angle = s.minmax_angle_from_center(center)
274
276
  self.min_angle = mm_angle[0]
@@ -286,6 +288,12 @@ class Area(object):
286
288
 
287
289
  self.alpha = round(alpha_angle(self.min_angle, self.max_angle), 3)
288
290
 
291
+ def center_is_inside(self, center):
292
+ if self.minmax_xy[0] < center[0] and self.minmax_xy[1] > center[0] and \
293
+ self.minmax_xy[2] < center[1] and self.minmax_xy[3] > center[1]:
294
+ return True
295
+ return False
296
+
289
297
  def minmax_angle_dist_from_center(self, center, dist):
290
298
  circ = Circle(Element(center=center, radius=dist))
291
299
  s = self.area[0]
@@ -429,6 +437,16 @@ class Area(object):
429
437
  (the_axis_p[0], the_axis_p[1]),
430
438
  (the_area_p[0], the_area_p[1]))
431
439
 
440
+ def get_alpha(self, center):
441
+ if self.center_is_inside(center):
442
+ return np.pi*2.0
443
+ return alpha_angle(self.min_angle, self.max_angle)
444
+
445
+ def get_mid_angle(self, center):
446
+ if self.center_is_inside(center):
447
+ return np.pi
448
+ return middle_angle(self.min_angle, self.max_angle)
449
+
432
450
  def is_equal(self, a, sym_tolerance):
433
451
  if sym_tolerance > 0.0:
434
452
  if np.isclose(round(self.min_dist, 4),
@@ -630,7 +648,7 @@ class Area(object):
630
648
  return False
631
649
 
632
650
  def get_best_point_inside(self, geom):
633
- mm = self.minmax()
651
+ mm = self.minmax_xy
634
652
  px1 = mm[0]-5
635
653
  px2 = mm[1]+5
636
654
 
@@ -727,7 +745,7 @@ class Area(object):
727
745
 
728
746
  def get_point_inside(self, geom):
729
747
  """return point inside area"""
730
- mm = self.minmax()
748
+ mm = self.minmax_xy
731
749
  y = (mm[2]+mm[3])/2
732
750
  p1 = (mm[0]-5, y)
733
751
  p2 = (mm[1]+5, y)
@@ -1460,6 +1478,14 @@ class Area(object):
1460
1478
  self.close_to_ag_endcorner = True
1461
1479
 
1462
1480
  def area_size(self):
1481
+ if len(self.area) == 0:
1482
+ return 0.0
1483
+ if self.number_of_elements() < 2:
1484
+ e = self.area[0]
1485
+ if not is_Circle(e):
1486
+ return 0.0
1487
+ return np.pi * e.radius**2
1488
+
1463
1489
  nodes = [n for n in self.list_of_nodes()]
1464
1490
  return area_size(nodes)
1465
1491
 
@@ -341,9 +341,11 @@ class AreaBuilder(object):
341
341
  def __init__(self,
342
342
  geom=None,
343
343
  rtol=1e-04,
344
- atol=1e-04):
344
+ atol=1e-04,
345
+ ndec=6):
345
346
  self.rtol = rtol
346
347
  self.atol = atol
348
+ self.ndec = ndec
347
349
  self.geom = geom
348
350
  self.area_list = []
349
351
  self.journal = getJournal()
@@ -358,7 +360,13 @@ class AreaBuilder(object):
358
360
 
359
361
  def set_edge_attributes(self):
360
362
  self.geom.set_edge_attributes()
361
-
363
+
364
+ def append_new_area(self, area_list, elements):
365
+ a = Area(elements, self.geom.center, 0.0)
366
+ a.type = 0 # air
367
+ area_list.append(a)
368
+ return a
369
+
362
370
  def create_list_of_areas(self, main=False):
363
371
  logger.debug("Begin of create_list_of_areas")
364
372
  assert(len(self.area_list) == 0)
@@ -382,10 +390,8 @@ class AreaBuilder(object):
382
390
  for next_n in nbrs:
383
391
  result = self.get_new_area(n, next_n)
384
392
  if result['ok']:
385
- area = result['area']
386
- a = Area(area, self.geom.center, 0.0)
393
+ a = self.append_new_area(self.area_list, result['area'])
387
394
  logger.debug("Area %s found", a.identifier())
388
- append(self.area_list, a)
389
395
 
390
396
  t = timer.stop("{} areas created in %0.4f seconds".format(len(self.area_list)))
391
397
  if main:
@@ -564,3 +570,144 @@ class AreaBuilder(object):
564
570
  nbr1.log_edge(">>>> LEFT")
565
571
  logger.debug("end of next_edge_lefthand_side")
566
572
  return nbr1
573
+
574
+ def create_inner_corner_auxiliary_areas(self):
575
+ logger.debug("begin of create_inner_corner_auxiliary_areas")
576
+ if not self.geom.is_inner:
577
+ logger.debug("end of create_inner_corner_auxiliary_areas: not inner")
578
+ return
579
+
580
+ self.set_edge_attributes()
581
+
582
+ start_cp, start_exists = self.geom.get_start_airgap_corner()
583
+ end_cp, end_exists = self.geom.get_end_airgap_corner()
584
+ if start_exists and end_exists:
585
+ logger.debug("end of create_inner_corner_auxiliary_areas: no aktion")
586
+ return
587
+
588
+ airgap_line, airgap_el = self.get_inner_airgap_line()
589
+ if not airgap_el:
590
+ logger.debug("end of create_inner_corner_auxiliary_areas: no airgapline found")
591
+ return
592
+
593
+ logger.debug("airgapline found !!")
594
+ airgap_nodes = [n for n in airgap_line[1:]]
595
+ del airgap_nodes[-1]
596
+
597
+ if not start_exists:
598
+ cp = self.geom.start_corners[-1]
599
+ logger.debug("Start Corner: %s -- %s", cp, start_cp)
600
+ start_line = Line(Element(start=cp, end=start_cp),
601
+ color='red',
602
+ linestyle='dotted')
603
+
604
+ start_cp = start_line.node2(self.ndec)
605
+ for n in airgap_nodes:
606
+ ag_line = Line(Element(start=start_cp, end=n))
607
+ points = self.geom.get_intersection_points(airgap_el, ag_line, n)
608
+ if not points: # no intersection
609
+ d = distance(self.geom.center, n)
610
+ if np.isclose(d, self.geom.max_radius):
611
+ self.geom.add_arc(start_cp,
612
+ n,
613
+ self.geom.center,
614
+ self.geom.max_radius,
615
+ color='red',
616
+ linestyle='dotted')
617
+ else:
618
+ self.geom.add_line(start_cp,
619
+ n,
620
+ color='red',
621
+ linestyle='dotted')
622
+ self.geom.add_edge(cp, start_cp, start_line)
623
+ result = self.get_new_area(start_cp, n)
624
+ if result['ok']:
625
+ self.append_new_area(self.geom.area_list,
626
+ result['area'])
627
+ self.geom.set_start_corners(self.geom.center, 0.0)
628
+ break
629
+
630
+ if not end_exists:
631
+ cp = self.geom.end_corners[-1]
632
+ logger.debug("End Corner: %s -- %s", cp, end_cp)
633
+ end_line = Line(Element(start=cp, end=end_cp),
634
+ color='red',
635
+ linestyle='dotted')
636
+ end_cp = end_line.node2(self.ndec)
637
+ airgap_nodes.reverse()
638
+ for n in airgap_nodes:
639
+ ag_line = Line(Element(start=end_cp, end=n))
640
+ points = self.geom.get_intersection_points(airgap_el, ag_line, n)
641
+ if not points: # no intersection
642
+ d = distance(self.geom.center, n)
643
+ if np.isclose(d, self.geom.max_radius):
644
+ self.geom.add_arc(n, end_cp,
645
+ self.geom.center,
646
+ self.geom.max_radius,
647
+ color='red',
648
+ linestyle='dotted')
649
+ else:
650
+ self.geom.add_line(end_cp, n,
651
+ color='red',
652
+ linestyle='dotted')
653
+ self.geom.add_edge(cp, end_cp, end_line)
654
+ result = self.get_new_area(n, end_cp)
655
+ if result['ok']:
656
+ self.append_new_area(self.geom.area_list,
657
+ result['area'])
658
+ self.geom.set_end_corners(self.geom.center, self.geom.alfa)
659
+ break
660
+
661
+ logger.debug("end of create_inner_corner_auxiliary_areas")
662
+
663
+ def get_inner_airgap_line(self):
664
+ logger.debug("begin of get_inner_airgap_line")
665
+ assert(self.geom.is_inner)
666
+ assert(self.geom.area_list)
667
+
668
+ area = [a for a in self.geom.area_list if a.close_to_ag_endcorner]
669
+ if len(area) != 1:
670
+ logger.debug("end of get_inner_airgap_line: %s areas found", len(area))
671
+ return [], []
672
+
673
+ end_corner = self.geom.end_corners[-1]
674
+ logger.debug("END CORNER %s", end_corner)
675
+
676
+ nodes = [n for n in area[0].list_of_nodes()]
677
+ if not nodes:
678
+ logger.debug("end of get_inner_airgap_line: no nodes found")
679
+ return [], []
680
+
681
+ n1 = nodes[0]
682
+ if points_are_close(end_corner, n1):
683
+ n2 = nodes[-1]
684
+ else:
685
+ n2 = n1
686
+ for n1 in nodes[1:]:
687
+ if points_are_close(end_corner, n1):
688
+ break
689
+ n2 = n1
690
+
691
+ if not points_are_close(end_corner, n1):
692
+ logger.debug("end of get_inner_airgap_line: not close to endcorner")
693
+ return [], []
694
+
695
+ start_corner = self.geom.start_corners[-1]
696
+ logger.debug("START CORNER %s", end_corner)
697
+
698
+ logger.debug("EDGE FOUND: %s - %s", n1, n2)
699
+ nodes = [n1, n2]
700
+ info = self.get_edge_info(n1, n2)
701
+ elements = [info.element]
702
+
703
+ while not points_are_close(start_corner, n2):
704
+ info.set_start_angle()
705
+ info = self.next_edge_lefthand_side(info)
706
+ if not info: # bad
707
+ return []
708
+ n2 = info.n2
709
+ nodes.append(n2)
710
+ elements.append(info.element)
711
+
712
+ logger.debug("end of get_inner_airgap_line #%s", len(nodes))
713
+ return nodes, elements
@@ -204,9 +204,9 @@ class Concatenation(object):
204
204
  elmts.sort()
205
205
 
206
206
  logger.debug("Concatenate Line Elements")
207
- for m, a, p, e in elmts:
208
- logger.debug("Line from %s to %s [m=%s, a=%s]",
209
- e.p1, e.p2, m, a)
207
+ #for m, a, p, e in elmts:
208
+ # logger.debug("Line from %s to %s [m=%s, a=%s]",
209
+ # e.p1, e.p2, m, a)
210
210
  logger.debug("*************************")
211
211
 
212
212
  lines_available = len(elmts)
@@ -281,9 +281,9 @@ class Concatenation(object):
281
281
  elmts.sort()
282
282
 
283
283
  logger.debug("Concatenate Arc Elements")
284
- for c, r, a, e in elmts:
285
- logger.debug("%s from %s to %s [c=%s, r=%s, a=%s]",
286
- e.classname(), e.p1, e.p2, c, r, a)
284
+ #for c, r, a, e in elmts:
285
+ # logger.debug("%s from %s to %s [c=%s, r=%s, a=%s]",
286
+ # e.classname(), e.p1, e.p2, c, r, a)
287
287
  logger.debug("*************************")
288
288
 
289
289
  arcs_available = len(elmts)
@@ -354,4 +354,4 @@ class Concatenation(object):
354
354
  self.journal.put('time_concatenation', t)
355
355
 
356
356
  logger.debug("End of concatenate_matching_elements")
357
- return count>0, new_list
357
+ return count, new_list
@@ -1,11 +1,12 @@
1
1
  """read a dxf file and create a plot or fsl file
2
2
 
3
3
  """
4
- import os
5
- from femagtools.dxfsl.geom import Geometry, dxfshapes, femshapes
4
+ from pathlib import Path
5
+ from femagtools.dxfsl.geom import Geometry
6
6
  from femagtools.dxfsl.shape import Shape
7
7
  from femagtools.dxfsl.fslrenderer import FslRenderer, agndst
8
8
  from femagtools.dxfsl.plotrenderer import PlotRenderer
9
+ from femagtools.dxfsl.functions import Timer
9
10
  import logging
10
11
  import logging.config
11
12
  import numpy as np
@@ -124,8 +125,9 @@ def convert(dxfile,
124
125
  layers = ()
125
126
  conv = {}
126
127
 
127
- basename = os.path.basename(dxfile).split('.')[0]
128
- logger.info("start processing %s", basename)
128
+ basename = Path(dxfile).stem
129
+ logger.info("***** start processing %s *****", basename)
130
+ timer = Timer(start_it=True)
129
131
 
130
132
  if part:
131
133
  if part[0] not in ('rotor', 'stator'):
@@ -149,18 +151,28 @@ def convert(dxfile,
149
151
  split_cpy = split
150
152
 
151
153
  try:
152
- if dxfile.split('.')[-1] == 'fem':
154
+ if Path(dxfile).suffix == '.fem':
155
+ from .femparser import femshapes
153
156
  basegeom = Geometry(femshapes(dxfile),
154
157
  rtol=rtol,
155
158
  atol=atol,
156
159
  split=split_ini)
157
- else:
160
+ elif Path(dxfile).suffix == '.dxf':
161
+ from .dxfparser import dxfshapes
158
162
  basegeom = Geometry(dxfshapes(dxfile,
159
163
  mindist=mindist,
160
164
  layers=layers),
161
165
  rtol=rtol,
162
166
  atol=atol,
163
167
  split=split_ini)
168
+ elif Path(dxfile).suffix == '.svg':
169
+ from .svgparser import svgshapes
170
+ basegeom = Geometry(svgshapes(dxfile),
171
+ rtol=rtol,
172
+ atol=atol,
173
+ split=split_ini)
174
+
175
+
164
176
  except FileNotFoundError as ex:
165
177
  logger.error(ex)
166
178
  return dict()
@@ -187,7 +199,7 @@ def convert(dxfile,
187
199
  machine_base = basegeom.get_machine()
188
200
  if show_plots:
189
201
  p.render_elements(basegeom, Shape,
190
- title=os.path.basename(dxfile),
202
+ title=Path(dxfile).name,
191
203
  with_hull=False,
192
204
  rows=3, cols=2, num=1, show=debug_mode)
193
205
 
@@ -490,6 +502,7 @@ def convert(dxfile,
490
502
  conv.update(params)
491
503
 
492
504
  conv['name'] = basename
505
+ timer.stop("-- all done in %0.4f seconds --")
493
506
  return conv
494
507
 
495
508