emerge 0.6.6__py3-none-any.whl → 0.6.7__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.
Potentially problematic release.
This version of emerge might be problematic. Click here for more details.
- emerge/__init__.py +1 -1
- emerge/_emerge/geo/__init__.py +1 -1
- emerge/_emerge/geo/operations.py +31 -4
- emerge/_emerge/geo/pcb.py +44 -9
- emerge/_emerge/geo/shapes.py +61 -26
- emerge/_emerge/physics/microwave/microwave_bc.py +2 -4
- emerge/_emerge/physics/microwave/microwave_data.py +13 -0
- emerge/_emerge/plot/pyvista/display.py +113 -15
- emerge/_emerge/simmodel.py +10 -8
- emerge/_emerge/solver.py +4 -4
- {emerge-0.6.6.dist-info → emerge-0.6.7.dist-info}/METADATA +1 -1
- {emerge-0.6.6.dist-info → emerge-0.6.7.dist-info}/RECORD +15 -15
- {emerge-0.6.6.dist-info → emerge-0.6.7.dist-info}/WHEEL +0 -0
- {emerge-0.6.6.dist-info → emerge-0.6.7.dist-info}/entry_points.txt +0 -0
- {emerge-0.6.6.dist-info → emerge-0.6.7.dist-info}/licenses/LICENSE +0 -0
emerge/__init__.py
CHANGED
emerge/_emerge/geo/__init__.py
CHANGED
|
@@ -19,6 +19,6 @@ from .pcb import PCB
|
|
|
19
19
|
from .pmlbox import pmlbox
|
|
20
20
|
from .horn import Horn
|
|
21
21
|
from .shapes import Cylinder, CoaxCylinder, Box, XYPlate, HalfSphere, Sphere, Plate, OldBox, Alignment, Cone
|
|
22
|
-
from .operations import subtract, add, embed, remove, rotate, mirror, change_coordinate_system, translate, intersect, unite
|
|
22
|
+
from .operations import subtract, add, embed, remove, rotate, mirror, change_coordinate_system, translate, intersect, unite, expand_surface
|
|
23
23
|
from .polybased import XYPolygon, GeoPrism, Disc, Curve
|
|
24
24
|
from .step import STEPItems
|
emerge/_emerge/geo/operations.py
CHANGED
|
@@ -60,7 +60,7 @@ def add(main: T, tool: T,
|
|
|
60
60
|
main._exists = False
|
|
61
61
|
if remove_tool:
|
|
62
62
|
tool._exists = False
|
|
63
|
-
return output # type: ignore
|
|
63
|
+
return output.set_material(main.material) # type: ignore
|
|
64
64
|
|
|
65
65
|
def remove(main: T, tool: T,
|
|
66
66
|
remove_object: bool = True,
|
|
@@ -90,7 +90,7 @@ def remove(main: T, tool: T,
|
|
|
90
90
|
main._exists = False
|
|
91
91
|
if remove_tool:
|
|
92
92
|
tool._exists = False
|
|
93
|
-
return output # type: ignore
|
|
93
|
+
return output.set_material(main.material) # type: ignore
|
|
94
94
|
|
|
95
95
|
subtract = remove
|
|
96
96
|
|
|
@@ -122,7 +122,7 @@ def intersect(main: T, tool: T,
|
|
|
122
122
|
main._exists = False
|
|
123
123
|
if remove_tool:
|
|
124
124
|
tool._exists = False
|
|
125
|
-
return output #type:ignore
|
|
125
|
+
return output.set_material(main.material) #type:ignore
|
|
126
126
|
|
|
127
127
|
def embed(main: GeoVolume, other: GeoSurface) -> None:
|
|
128
128
|
''' Embeds a surface into a volume in the GMSH model.
|
|
@@ -301,4 +301,31 @@ def unite(*objects: GeoObject) -> GeoObject:
|
|
|
301
301
|
new_obj.set_material(main.material)
|
|
302
302
|
new_obj.prio_set(main._priority)
|
|
303
303
|
|
|
304
|
-
return new_obj
|
|
304
|
+
return new_obj
|
|
305
|
+
|
|
306
|
+
def expand_surface(surface: GeoSurface, distance: float) -> GeoSurface:
|
|
307
|
+
"""EXPERIMENTAL: Expands an input surface. The surface must exist on a 2D plane.
|
|
308
|
+
|
|
309
|
+
The output surface does not inherit material properties.
|
|
310
|
+
|
|
311
|
+
If any problems occur, reach out through email.
|
|
312
|
+
|
|
313
|
+
Args:
|
|
314
|
+
surface (GeoSurface): The input surface to expand
|
|
315
|
+
distance (float): The exapansion distance
|
|
316
|
+
|
|
317
|
+
Returns:
|
|
318
|
+
GeoSurface: The output surface
|
|
319
|
+
"""
|
|
320
|
+
surfs = []
|
|
321
|
+
for tag in surface.tags:
|
|
322
|
+
looptags, _ = gmsh.model.occ.get_curve_loops(tag)
|
|
323
|
+
new_curves = []
|
|
324
|
+
for looptag in looptags:
|
|
325
|
+
curve_tags = gmsh.model.occ.offset_curve(looptag, distance)
|
|
326
|
+
loop_tag = gmsh.model.occ.addCurveLoop([t for d,t in curve_tags])
|
|
327
|
+
new_curves.append(loop_tag)
|
|
328
|
+
surftag = gmsh.model.occ.addPlaneSurface(new_curves)
|
|
329
|
+
surfs.append(surftag)
|
|
330
|
+
surf = GeoSurface(surfs)
|
|
331
|
+
return surf
|
emerge/_emerge/geo/pcb.py
CHANGED
|
@@ -963,8 +963,18 @@ class PCB:
|
|
|
963
963
|
Returns:
|
|
964
964
|
float: the z-height
|
|
965
965
|
"""
|
|
966
|
+
if layer <= 0:
|
|
967
|
+
return self._zs[layer]
|
|
966
968
|
return self._zs[layer-1]
|
|
967
969
|
|
|
970
|
+
@property
|
|
971
|
+
def top(self) -> float:
|
|
972
|
+
return self._zs[-1]
|
|
973
|
+
|
|
974
|
+
@property
|
|
975
|
+
def bottom(self) -> float:
|
|
976
|
+
return self._zs[0]
|
|
977
|
+
|
|
968
978
|
def _get_z(self, element: RouteElement) -> float :
|
|
969
979
|
"""Return the z-height of a given Route Element
|
|
970
980
|
|
|
@@ -979,6 +989,31 @@ class PCB:
|
|
|
979
989
|
return path.z
|
|
980
990
|
raise RouteException('Requesting z-height of route element that is not contained in a path.')
|
|
981
991
|
|
|
992
|
+
def add_vias(self, *coordinates: tuple[float, float], radius: float,
|
|
993
|
+
z1: float | None = None,
|
|
994
|
+
z2: float | None = None,
|
|
995
|
+
segments: int = 6) -> None:
|
|
996
|
+
"""Add a series of vias provided by a list of coordinates.
|
|
997
|
+
|
|
998
|
+
Make sure to define the radius explicitly, otherwise the radius gets interpreted as a coordinate:
|
|
999
|
+
|
|
1000
|
+
>>> pcb.add_vias((x1,y1), (x1,y2), radius=1)
|
|
1001
|
+
|
|
1002
|
+
Args:
|
|
1003
|
+
*coordinates (tuple(float, float)): A series of coordinates
|
|
1004
|
+
radius (float): The radius
|
|
1005
|
+
z1 (float | None, optional): The bottom z-coordinate. Defaults to None.
|
|
1006
|
+
z2 (float | None, optional): The top z-coordinate. Defaults to None.
|
|
1007
|
+
segments (int, optional): The number of segmets for the via. Defaults to 6.
|
|
1008
|
+
"""
|
|
1009
|
+
if z1 is None:
|
|
1010
|
+
z1 = self.z(0)
|
|
1011
|
+
if z2 is None:
|
|
1012
|
+
z2 = self.z(-1)
|
|
1013
|
+
|
|
1014
|
+
for x,y in coordinates:
|
|
1015
|
+
self.vias.append(Via(x,y,z1,z2,radius,segments))
|
|
1016
|
+
|
|
982
1017
|
def load(self, name: str) -> StripLine:
|
|
983
1018
|
"""Acquire the x,y, coordinate associated with the label name.
|
|
984
1019
|
|
|
@@ -1060,7 +1095,7 @@ class PCB:
|
|
|
1060
1095
|
GeoSurface: _description_
|
|
1061
1096
|
"""
|
|
1062
1097
|
if width is None or height is None or origin is None:
|
|
1063
|
-
if self.width is None or self.length is None or self.origin:
|
|
1098
|
+
if self.width is None or self.length is None or self.origin is None:
|
|
1064
1099
|
raise RouteException('Cannot define a plane with no possible definition of its size.')
|
|
1065
1100
|
width = self.width
|
|
1066
1101
|
height = self.length
|
|
@@ -1075,6 +1110,7 @@ class PCB:
|
|
|
1075
1110
|
|
|
1076
1111
|
plane = Plate(origin, (width*self.unit, 0, 0), (0, height*self.unit, 0)) # type: ignore
|
|
1077
1112
|
plane = change_coordinate_system(plane, self.cs) # type: ignore
|
|
1113
|
+
plane.set_material(COPPER)
|
|
1078
1114
|
return plane # type: ignore
|
|
1079
1115
|
|
|
1080
1116
|
def generate_pcb(self,
|
|
@@ -1121,7 +1157,7 @@ class PCB:
|
|
|
1121
1157
|
"""Generate the Air Block object
|
|
1122
1158
|
|
|
1123
1159
|
This requires that the width, depth and origin are deterimed. This
|
|
1124
|
-
can either be done manually or via the .
|
|
1160
|
+
can either be done manually or via the .determine_bounds() method.
|
|
1125
1161
|
|
|
1126
1162
|
Returns:
|
|
1127
1163
|
GeoVolume: The PCB Block
|
|
@@ -1357,20 +1393,19 @@ class PCB:
|
|
|
1357
1393
|
poly = self._gen_poly(pcbpoly.xys, pcbpoly.z)
|
|
1358
1394
|
poly.material = pcbpoly.material
|
|
1359
1395
|
polys.append(poly)
|
|
1396
|
+
xs, ys = zip(*pcbpoly.xys)
|
|
1397
|
+
allx.extend(xs)
|
|
1398
|
+
ally.extend(ys)
|
|
1399
|
+
|
|
1360
1400
|
|
|
1361
1401
|
self.xs = allx
|
|
1362
1402
|
self.ys = ally
|
|
1363
1403
|
|
|
1364
1404
|
self.traces = polys
|
|
1405
|
+
|
|
1365
1406
|
if merge:
|
|
1366
1407
|
polys = unite(*polys)
|
|
1367
|
-
|
|
1368
|
-
# for p in polys:
|
|
1369
|
-
# tags.extend(p.tags)
|
|
1370
|
-
# if p.material != COPPER:
|
|
1371
|
-
# logger.warning(f'Merging a polygon with material {p.material} into a single polygon that will be COPPER.')
|
|
1372
|
-
# polys = GeoSurface(tags)
|
|
1373
|
-
# polys.material = COPPER
|
|
1408
|
+
|
|
1374
1409
|
return polys
|
|
1375
1410
|
|
|
1376
1411
|
############################################################
|
emerge/_emerge/geo/shapes.py
CHANGED
|
@@ -30,6 +30,7 @@ class Alignment(Enum):
|
|
|
30
30
|
CENTER = 1
|
|
31
31
|
CORNER = 2
|
|
32
32
|
|
|
33
|
+
|
|
33
34
|
class Box(GeoVolume):
|
|
34
35
|
"""Creates a box volume object.
|
|
35
36
|
Specify the alignment of the box with the provided position. The options are CORNER (default)
|
|
@@ -100,7 +101,7 @@ class Box(GeoVolume):
|
|
|
100
101
|
|
|
101
102
|
tags = list(reduce(lambda a,b: a+b, tagslist))
|
|
102
103
|
return FaceSelection(tags)
|
|
103
|
-
|
|
104
|
+
|
|
104
105
|
|
|
105
106
|
class Sphere(GeoVolume):
|
|
106
107
|
"""Generates a sphere objected centered ont he position with the given radius
|
|
@@ -122,6 +123,7 @@ class Sphere(GeoVolume):
|
|
|
122
123
|
x,y,z = position
|
|
123
124
|
self.tags: list[int] = [gmsh.model.occ.addSphere(x,y,z,radius),]
|
|
124
125
|
|
|
126
|
+
|
|
125
127
|
class XYPlate(GeoSurface):
|
|
126
128
|
"""Generates and XY-plane oriented plate
|
|
127
129
|
|
|
@@ -209,27 +211,43 @@ class Plate(GeoSurface):
|
|
|
209
211
|
tags: list[int] = [gmsh.model.occ.addPlaneSurface([tag_wire,]),]
|
|
210
212
|
super().__init__(tags)
|
|
211
213
|
|
|
214
|
+
|
|
212
215
|
class Cylinder(GeoVolume):
|
|
216
|
+
"""Generates a Cylinder object in 3D space.
|
|
217
|
+
The cylinder will always be placed in the origin of the provided CoordinateSystem.
|
|
218
|
+
The bottom cylinder plane is always placed in the XY-plane. The length of the cylinder is
|
|
219
|
+
oriented along the Z-axis.
|
|
213
220
|
|
|
221
|
+
By default the cylinder uses the Open Cascade modeling for a cylinder. In this representation
|
|
222
|
+
the surface of the cylinder is approximated with a tolerance thay may be irregular.
|
|
223
|
+
As an alternative, the argument Nsections may be provided in which case the Cylinder is replaced
|
|
224
|
+
by an extrusion of a regular N-sided polygon.
|
|
225
|
+
|
|
226
|
+
Args:
|
|
227
|
+
radius (float): The radius of the Cylinder
|
|
228
|
+
height (float): The height of the Cylinder
|
|
229
|
+
cs (CoordinateSystem, optional): The coordinate system. Defaults to GCS.
|
|
230
|
+
Nsections (int, optional): The number of sections. Defaults to None.
|
|
231
|
+
"""
|
|
214
232
|
def __init__(self,
|
|
215
233
|
radius: float,
|
|
216
234
|
height: float,
|
|
217
|
-
cs: CoordinateSystem =
|
|
218
|
-
Nsections: int = None):
|
|
235
|
+
cs: CoordinateSystem = GCS,
|
|
236
|
+
Nsections: int | None = None):
|
|
219
237
|
"""Generates a Cylinder object in 3D space.
|
|
220
|
-
The
|
|
221
|
-
The bottom
|
|
238
|
+
The cylinder will always be placed in the origin of the provided CoordinateSystem.
|
|
239
|
+
The bottom cylinder plane is always placed in the XY-plane. The length of the cylinder is
|
|
222
240
|
oriented along the Z-axis.
|
|
223
241
|
|
|
224
|
-
By default the
|
|
225
|
-
the surface of the
|
|
242
|
+
By default the cylinder uses the Open Cascade modeling for a cylinder. In this representation
|
|
243
|
+
the surface of the cylinder is approximated with a tolerance thay may be irregular.
|
|
226
244
|
As an alternative, the argument Nsections may be provided in which case the Cylinder is replaced
|
|
227
245
|
by an extrusion of a regular N-sided polygon.
|
|
228
246
|
|
|
229
247
|
Args:
|
|
230
248
|
radius (float): The radius of the Cylinder
|
|
231
249
|
height (float): The height of the Cylinder
|
|
232
|
-
cs (CoordinateSystem, optional): The coordinate system. Defaults to
|
|
250
|
+
cs (CoordinateSystem, optional): The coordinate system. Defaults to GCS.
|
|
233
251
|
Nsections (int, optional): The number of sections. Defaults to None.
|
|
234
252
|
"""
|
|
235
253
|
ax = cs.zax.np
|
|
@@ -270,33 +288,46 @@ class Cylinder(GeoVolume):
|
|
|
270
288
|
xo, yo, zo = self.cs.in_global_cs(x.flatten(), y.flatten(), z.flatten())
|
|
271
289
|
return xo, yo, zo
|
|
272
290
|
|
|
291
|
+
|
|
273
292
|
class CoaxCylinder(GeoVolume):
|
|
274
|
-
"""
|
|
275
|
-
|
|
293
|
+
"""Generates a Coaxial cylinder object in 3D space.
|
|
294
|
+
The coaxial cylinder will always be placed in the origin of the provided CoordinateSystem.
|
|
295
|
+
The bottom coax plane is always placed in the XY-plane. The lenth of the coax is
|
|
296
|
+
oriented along the Z-axis.
|
|
297
|
+
|
|
298
|
+
By default the coax uses the Open Cascade modeling for a cylinder. In this representation
|
|
299
|
+
the surface of the cylinder is approximated with a tolerance thay may be irregular.
|
|
300
|
+
As an alternative, the argument Nsections may be provided in which case the Cylinder is replaced
|
|
301
|
+
by an extrusion of a regular N-sided polygon.
|
|
302
|
+
|
|
303
|
+
Args:
|
|
304
|
+
radius (float): The radius of the Cylinder
|
|
305
|
+
height (float): The height of the Cylinder
|
|
306
|
+
cs (CoordinateSystem, optional): The coordinate system. Defaults to GCS.
|
|
307
|
+
Nsections (int, optional): The number of sections. Defaults to None.
|
|
308
|
+
"""
|
|
276
309
|
def __init__(self,
|
|
277
310
|
rout: float,
|
|
278
311
|
rin: float,
|
|
279
312
|
height: float,
|
|
280
|
-
cs: CoordinateSystem =
|
|
281
|
-
Nsections: int = None):
|
|
282
|
-
"""Generates a Coaxial
|
|
283
|
-
The coaxial
|
|
313
|
+
cs: CoordinateSystem = GCS,
|
|
314
|
+
Nsections: int | None = None):
|
|
315
|
+
"""Generates a Coaxial cylinder object in 3D space.
|
|
316
|
+
The coaxial cylinder will always be placed in the origin of the provided CoordinateSystem.
|
|
284
317
|
The bottom coax plane is always placed in the XY-plane. The lenth of the coax is
|
|
285
318
|
oriented along the Z-axis.
|
|
286
319
|
|
|
287
|
-
By default the coax uses the Open Cascade modeling for a
|
|
288
|
-
the surface of the
|
|
320
|
+
By default the coax uses the Open Cascade modeling for a cylinder. In this representation
|
|
321
|
+
the surface of the cylinder is approximated with a tolerance thay may be irregular.
|
|
289
322
|
As an alternative, the argument Nsections may be provided in which case the Cylinder is replaced
|
|
290
323
|
by an extrusion of a regular N-sided polygon.
|
|
291
324
|
|
|
292
325
|
Args:
|
|
293
326
|
radius (float): The radius of the Cylinder
|
|
294
327
|
height (float): The height of the Cylinder
|
|
295
|
-
cs (CoordinateSystem, optional): The coordinate system. Defaults to
|
|
328
|
+
cs (CoordinateSystem, optional): The coordinate system. Defaults to GCS.
|
|
296
329
|
Nsections (int, optional): The number of sections. Defaults to None.
|
|
297
330
|
"""
|
|
298
|
-
if cs is None:
|
|
299
|
-
cs = GCS
|
|
300
331
|
if rout <= rin:
|
|
301
332
|
raise ValueError("Outer radius must be greater than inner radius.")
|
|
302
333
|
|
|
@@ -336,7 +367,7 @@ class CoaxCylinder(GeoVolume):
|
|
|
336
367
|
return xo, yo, zo
|
|
337
368
|
|
|
338
369
|
class HalfSphere(GeoVolume):
|
|
339
|
-
|
|
370
|
+
"""A half sphere volume."""
|
|
340
371
|
def __init__(self,
|
|
341
372
|
radius: float,
|
|
342
373
|
position: tuple = (0,0,0),
|
|
@@ -362,8 +393,6 @@ class HalfSphere(GeoVolume):
|
|
|
362
393
|
self._add_face_pointer('back',np.array(position), np.array(direction))
|
|
363
394
|
self._add_face_pointer('bottom',np.array(position), np.array(direction))
|
|
364
395
|
self._add_face_pointer('face',np.array(position), np.array(direction))
|
|
365
|
-
|
|
366
|
-
|
|
367
396
|
|
|
368
397
|
|
|
369
398
|
class OldBox(GeoVolume):
|
|
@@ -389,8 +418,6 @@ class OldBox(GeoVolume):
|
|
|
389
418
|
alignment (Alignment, optional): Which point of the box is placed at the position.
|
|
390
419
|
Defaults to Alignment.CORNER.
|
|
391
420
|
"""
|
|
392
|
-
|
|
393
|
-
|
|
394
421
|
if alignment is Alignment.CORNER:
|
|
395
422
|
position = (position[0]+width/2, position[1]+depth/2, position[2])
|
|
396
423
|
elif alignment is Alignment.CENTER:
|
|
@@ -472,7 +499,6 @@ class OldBox(GeoVolume):
|
|
|
472
499
|
self._add_face_pointer('right', pc + width/2*wax, wax)
|
|
473
500
|
self._add_face_pointer('top', pc + height/2*hax, hax)
|
|
474
501
|
self._add_face_pointer('bottom', pc - height/2*hax, -hax)
|
|
475
|
-
|
|
476
502
|
|
|
477
503
|
def outside(self, *exclude: Literal['bottom','top','right','left','front','back']) -> FaceSelection:
|
|
478
504
|
"""Select all outside faces except for the once specified by outside
|
|
@@ -485,8 +511,17 @@ class OldBox(GeoVolume):
|
|
|
485
511
|
tags = list(reduce(lambda a,b: a+b, tagslist))
|
|
486
512
|
return FaceSelection(tags)
|
|
487
513
|
|
|
514
|
+
|
|
488
515
|
class Cone(GeoVolume):
|
|
489
|
-
|
|
516
|
+
"""Constructis a cone that starts at position p0 and is aimed in the given direction.
|
|
517
|
+
r1 is the start radius and r2 the end radius. The magnitude of direction determines its length.
|
|
518
|
+
|
|
519
|
+
Args:
|
|
520
|
+
p0 (tuple[float, float, float]): _description_
|
|
521
|
+
direction (tuple[float, float, float]): _description_
|
|
522
|
+
r1 (float): _description_
|
|
523
|
+
r2 (float): _description_
|
|
524
|
+
"""
|
|
490
525
|
def __init__(self, p0: tuple[float, float, float],
|
|
491
526
|
direction: tuple[float, float, float],
|
|
492
527
|
r1: float,
|
|
@@ -787,7 +787,6 @@ class LumpedPort(PortBC):
|
|
|
787
787
|
width: float | None = None,
|
|
788
788
|
height: float | None = None,
|
|
789
789
|
direction: Axis | None = None,
|
|
790
|
-
Idirection: Axis | None = None,
|
|
791
790
|
active: bool = False,
|
|
792
791
|
power: float = 1,
|
|
793
792
|
Z0: float = 50):
|
|
@@ -814,7 +813,7 @@ class LumpedPort(PortBC):
|
|
|
814
813
|
if width is None:
|
|
815
814
|
if not isinstance(face, GeoObject):
|
|
816
815
|
raise ValueError(f'The width, height and direction must be defined. Information cannot be extracted from {face}')
|
|
817
|
-
width, height, direction
|
|
816
|
+
width, height, direction = face._data('width','height','vdir')
|
|
818
817
|
if width is None or height is None or direction is None:
|
|
819
818
|
raise ValueError(f'The width, height and direction could not be extracted from {face}')
|
|
820
819
|
|
|
@@ -828,7 +827,6 @@ class LumpedPort(PortBC):
|
|
|
828
827
|
self.width: float = width
|
|
829
828
|
self.height: float = height # type: ignore
|
|
830
829
|
self.Vdirection: Axis = direction # type: ignore
|
|
831
|
-
self.Idirection: Axis = Idirection # type: ignore
|
|
832
830
|
self.type = 'TEM'
|
|
833
831
|
|
|
834
832
|
logger.info('Constructing coordinate system from normal port')
|
|
@@ -836,7 +834,6 @@ class LumpedPort(PortBC):
|
|
|
836
834
|
|
|
837
835
|
self.vintline: Line | None = None
|
|
838
836
|
self.v_integration = True
|
|
839
|
-
self.iintline: Line | None = None
|
|
840
837
|
|
|
841
838
|
@property
|
|
842
839
|
def surfZ(self) -> float:
|
|
@@ -923,6 +920,7 @@ class LumpedPort(PortBC):
|
|
|
923
920
|
Exg, Eyg, Ezg = self.cs.in_global_basis(Ex, Ey, Ez)
|
|
924
921
|
return np.array([Exg, Eyg, Ezg])
|
|
925
922
|
|
|
923
|
+
|
|
926
924
|
class LumpedElement(RobinBC):
|
|
927
925
|
|
|
928
926
|
_include_stiff: bool = True
|
|
@@ -731,6 +731,19 @@ class MWField:
|
|
|
731
731
|
x: float | None = None,
|
|
732
732
|
y: float | None = None,
|
|
733
733
|
z: float | None = None) -> EHField:
|
|
734
|
+
"""Create a cartesian cut plane (XY, YZ or XZ) and compute the E and H-fields there
|
|
735
|
+
|
|
736
|
+
Only one coordiante and thus cutplane may be defined. If multiple are defined only the last (x->y->z) is used.
|
|
737
|
+
|
|
738
|
+
Args:
|
|
739
|
+
ds (float): The discretization step size
|
|
740
|
+
x (float | None, optional): The X-coordinate in case of a YZ-plane. Defaults to None.
|
|
741
|
+
y (float | None, optional): The Y-coordinate in case of an XZ-plane. Defaults to None.
|
|
742
|
+
z (float | None, optional): The Z-coordinate in case of an XY-plane. Defaults to None.
|
|
743
|
+
|
|
744
|
+
Returns:
|
|
745
|
+
EHField: The resultant EHField object
|
|
746
|
+
"""
|
|
734
747
|
xb, yb, zb = self.basis.bounds
|
|
735
748
|
xs = np.linspace(xb[0], xb[1], int((xb[1]-xb[0])/ds))
|
|
736
749
|
ys = np.linspace(yb[0], yb[1], int((yb[1]-yb[0])/ds))
|
|
@@ -26,7 +26,7 @@ from typing import Iterable, Literal, Callable, Any
|
|
|
26
26
|
from ..display import BaseDisplay
|
|
27
27
|
from .display_settings import PVDisplaySettings
|
|
28
28
|
from matplotlib.colors import ListedColormap
|
|
29
|
-
|
|
29
|
+
from itertools import cycle
|
|
30
30
|
### Color scale
|
|
31
31
|
|
|
32
32
|
# Define the colors we want to use
|
|
@@ -40,6 +40,40 @@ cmap_names = Literal['bgy','bgyw','kbc','blues','bmw','bmy','kgy','gray','dimgra
|
|
|
40
40
|
'bkr','bky','coolwarm','gwv','bjy','bwy','cwr','colorwheel','isolum','rainbow','fire',
|
|
41
41
|
'cet_fire','gouldian','kbgyw','cwr','CET_CBL1','CET_CBL3','CET_D1A']
|
|
42
42
|
|
|
43
|
+
|
|
44
|
+
def _gen_c_cycle():
|
|
45
|
+
colors = [
|
|
46
|
+
"#0000aa",
|
|
47
|
+
"#aa0000",
|
|
48
|
+
"#009900",
|
|
49
|
+
"#990099",
|
|
50
|
+
"#994400",
|
|
51
|
+
"#005588"
|
|
52
|
+
]
|
|
53
|
+
return cycle(colors)
|
|
54
|
+
|
|
55
|
+
C_CYCLE = _gen_c_cycle()
|
|
56
|
+
|
|
57
|
+
class _RunState:
|
|
58
|
+
|
|
59
|
+
def __init__(self):
|
|
60
|
+
self.state: bool = False
|
|
61
|
+
self.ctr: int = 0
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def run(self):
|
|
65
|
+
self.state = True
|
|
66
|
+
self.ctr = 0
|
|
67
|
+
|
|
68
|
+
def stop(self):
|
|
69
|
+
self.state = False
|
|
70
|
+
self.ctr = 0
|
|
71
|
+
|
|
72
|
+
def step(self):
|
|
73
|
+
self.ctr += 1
|
|
74
|
+
|
|
75
|
+
ANIM_STATE = _RunState()
|
|
76
|
+
|
|
43
77
|
def gen_cmap(mesh, N: int = 256):
|
|
44
78
|
# build a linear grid of data‐values (not strictly needed for pure colormap)
|
|
45
79
|
vmin, vmax = mesh['values'].min(), mesh['values'].max()
|
|
@@ -201,6 +235,7 @@ class PVDisplay(BaseDisplay):
|
|
|
201
235
|
self._stop: bool = False
|
|
202
236
|
self._objs: list[_AnimObject] = []
|
|
203
237
|
self._do_animate: bool = False
|
|
238
|
+
self._closed_via_x: bool = False
|
|
204
239
|
self._Nsteps: int = 0
|
|
205
240
|
self._fps: int = 25
|
|
206
241
|
self._ruler: ScreenRuler = ScreenRuler(self, 0.001)
|
|
@@ -216,6 +251,15 @@ class PVDisplay(BaseDisplay):
|
|
|
216
251
|
self._ctr: int = 0
|
|
217
252
|
|
|
218
253
|
self.camera_position = (1, -1, 1) # +X, +Z, -Y
|
|
254
|
+
|
|
255
|
+
def _wire_close_events(self):
|
|
256
|
+
self._closed = False
|
|
257
|
+
|
|
258
|
+
def mark_closed(*_):
|
|
259
|
+
self._closed = True
|
|
260
|
+
self._stop = True
|
|
261
|
+
|
|
262
|
+
self._plot.add_key_event('q', lambda: mark_closed())
|
|
219
263
|
|
|
220
264
|
def _update_camera(self):
|
|
221
265
|
x,y,z = self._plot.camera.position
|
|
@@ -241,8 +285,12 @@ class PVDisplay(BaseDisplay):
|
|
|
241
285
|
self._update_camera()
|
|
242
286
|
self._add_aux_items()
|
|
243
287
|
if self._do_animate:
|
|
288
|
+
self._wire_close_events()
|
|
289
|
+
self.add_text('Press Q to close!',color='red', position='upper_left')
|
|
244
290
|
self._plot.show(auto_close=False, interactive_update=True, before_close_callback=self._close_callback)
|
|
245
291
|
self._animate()
|
|
292
|
+
|
|
293
|
+
|
|
246
294
|
else:
|
|
247
295
|
self._plot.show()
|
|
248
296
|
self._reset()
|
|
@@ -261,25 +309,55 @@ class PVDisplay(BaseDisplay):
|
|
|
261
309
|
self._plot = pv.Plotter()
|
|
262
310
|
self._stop = False
|
|
263
311
|
self._objs = []
|
|
312
|
+
C_CYCLE = _gen_c_cycle()
|
|
264
313
|
|
|
265
|
-
def _close_callback(self):
|
|
314
|
+
def _close_callback(self, arg):
|
|
266
315
|
"""The private callback function that stops the animation.
|
|
267
316
|
"""
|
|
268
317
|
self._stop = True
|
|
318
|
+
print('CLOSE!')
|
|
269
319
|
|
|
270
320
|
def _animate(self) -> None:
|
|
271
321
|
"""Private function that starts the animation loop.
|
|
272
322
|
"""
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
323
|
+
|
|
324
|
+
self._stop = False
|
|
325
|
+
|
|
326
|
+
# guard values
|
|
327
|
+
steps = max(1, int(self._Nsteps))
|
|
328
|
+
fps = max(1, int(self._fps))
|
|
329
|
+
dt = 1.0 / fps
|
|
330
|
+
next_tick = time.perf_counter()
|
|
331
|
+
step = 0
|
|
332
|
+
|
|
333
|
+
while (not self._stop
|
|
334
|
+
and not self._closed_via_x
|
|
335
|
+
and self._plot.render_window is not None):
|
|
336
|
+
# process window/UI events so close button works
|
|
337
|
+
self._plot.update()
|
|
338
|
+
|
|
339
|
+
now = time.perf_counter()
|
|
340
|
+
if now >= next_tick:
|
|
341
|
+
step = (step + 1) % steps
|
|
342
|
+
phi = np.exp(1j * (step / steps) * 2*np.pi)
|
|
343
|
+
|
|
344
|
+
# update all animated objects
|
|
278
345
|
for aobj in self._objs:
|
|
279
|
-
phi = np.exp(1j*(step/self._Nsteps)*2*np.pi)
|
|
280
346
|
aobj.update(phi)
|
|
281
|
-
|
|
282
|
-
|
|
347
|
+
|
|
348
|
+
# draw one frame
|
|
349
|
+
self._plot.render()
|
|
350
|
+
|
|
351
|
+
# schedule next frame; catch up if we fell behind
|
|
352
|
+
next_tick += dt
|
|
353
|
+
if now > next_tick + dt:
|
|
354
|
+
next_tick = now + dt
|
|
355
|
+
|
|
356
|
+
# be kind to the CPU
|
|
357
|
+
time.sleep(0.001)
|
|
358
|
+
|
|
359
|
+
# ensure cleanup pathway runs once
|
|
360
|
+
self._close_callback(None)
|
|
283
361
|
|
|
284
362
|
def animate(self, Nsteps: int = 35, fps: int = 25) -> PVDisplay:
|
|
285
363
|
""" Turns on the animation mode with the specified number of steps and FPS.
|
|
@@ -357,11 +435,29 @@ class PVDisplay(BaseDisplay):
|
|
|
357
435
|
return None
|
|
358
436
|
|
|
359
437
|
## OBLIGATORY METHODS
|
|
360
|
-
def add_object(self, obj: GeoObject | Selection, *args, **kwargs):
|
|
361
|
-
|
|
438
|
+
def add_object(self, obj: GeoObject | Selection, mesh: bool = False, volume_mesh: bool = True, *args, **kwargs):
|
|
439
|
+
|
|
440
|
+
show_edges = False
|
|
441
|
+
opacity = obj.opacity
|
|
442
|
+
line_width = 0.5
|
|
443
|
+
color = obj.color_rgb
|
|
444
|
+
style='surface'
|
|
445
|
+
|
|
446
|
+
if mesh is True:
|
|
447
|
+
show_edges = True
|
|
448
|
+
opacity = 0.7
|
|
449
|
+
line_width= 1
|
|
450
|
+
style='wireframe'
|
|
451
|
+
color=next(C_CYCLE)
|
|
452
|
+
|
|
453
|
+
kwargs = setdefault(kwargs, color=color, opacity=opacity, line_width=line_width, show_edges=show_edges, pickable=True, style=style)
|
|
454
|
+
mesh_obj = self.mesh(obj)
|
|
362
455
|
|
|
363
|
-
|
|
364
|
-
|
|
456
|
+
if mesh is True and volume_mesh is True:
|
|
457
|
+
mesh_obj = mesh_obj.extract_all_edges()
|
|
458
|
+
|
|
459
|
+
actor = self._plot.add_mesh(mesh_obj, *args, **kwargs)
|
|
460
|
+
self._plot.add_mesh(self._volume_edges(_select(obj)), color='#000000', line_width=2, show_edges=True)
|
|
365
461
|
|
|
366
462
|
def add_scatter(self, xs: np.ndarray, ys: np.ndarray, zs: np.ndarray):
|
|
367
463
|
"""Adds a scatter point cloud
|
|
@@ -501,7 +597,7 @@ class PVDisplay(BaseDisplay):
|
|
|
501
597
|
if self._do_animate:
|
|
502
598
|
def on_update(obj: _AnimObject, phi: complex):
|
|
503
599
|
field = obj.T(np.real(obj.field*phi))
|
|
504
|
-
obj.grid[
|
|
600
|
+
obj.grid[name] = field
|
|
505
601
|
self._objs.append(_AnimObject(field_flat, T, grid, actor, on_update)) # type: ignore
|
|
506
602
|
|
|
507
603
|
|
|
@@ -524,6 +620,8 @@ class PVDisplay(BaseDisplay):
|
|
|
524
620
|
if abs_position is not None:
|
|
525
621
|
final_position = abs_position
|
|
526
622
|
viewport = True
|
|
623
|
+
else:
|
|
624
|
+
final_position = abs_position
|
|
527
625
|
self._plot.add_text(
|
|
528
626
|
text,
|
|
529
627
|
position=final_position,
|
emerge/_emerge/simmodel.py
CHANGED
|
@@ -319,24 +319,26 @@ class Simulation:
|
|
|
319
319
|
def view(self,
|
|
320
320
|
selections: list[Selection] | None = None,
|
|
321
321
|
use_gmsh: bool = False,
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
322
|
+
plot_mesh: bool = False,
|
|
323
|
+
volume_mesh: bool = True,
|
|
324
|
+
opacity: float | None = None) -> None:
|
|
325
325
|
"""View the current geometry in either the BaseDisplay object (PVDisplay only) or
|
|
326
326
|
the GMSH viewer.
|
|
327
327
|
|
|
328
328
|
Args:
|
|
329
|
-
selections (list[Selection], optional):
|
|
330
|
-
use_gmsh (bool, optional):
|
|
331
|
-
|
|
332
|
-
|
|
329
|
+
selections (list[Selection] | None, optional): Optional selections to highlight. Defaults to None.
|
|
330
|
+
use_gmsh (bool, optional): If GMSH's GUI should be used. Defaults to False.
|
|
331
|
+
plot_mesh (bool, optional): If the mesh should be plot instead of the object. Defaults to False.
|
|
332
|
+
volume_mesh (bool, optional): If the internal mesh should be plot instead of only the surface boundary mesh. Defaults to True
|
|
333
|
+
opacity (float | None, optional): The object/mesh opacity. Defaults to None.
|
|
334
|
+
|
|
333
335
|
"""
|
|
334
336
|
if not (self.display is not None and self.mesh.defined) or use_gmsh:
|
|
335
337
|
gmsh.model.occ.synchronize()
|
|
336
338
|
gmsh.fltk.run()
|
|
337
339
|
return
|
|
338
340
|
for geo in _GEOMANAGER.all_geometries():
|
|
339
|
-
self.display.add_object(geo)
|
|
341
|
+
self.display.add_object(geo, mesh=plot_mesh, opacity=opacity, volume_mesh=volume_mesh)
|
|
340
342
|
if selections:
|
|
341
343
|
[self.display.add_object(sel, color='red', opacity=0.3) for sel in selections]
|
|
342
344
|
self.display.show()
|
emerge/_emerge/solver.py
CHANGED
|
@@ -674,7 +674,7 @@ class SolverARPACK(EigSolver):
|
|
|
674
674
|
target_k0: float = 0,
|
|
675
675
|
which: str = 'LM',
|
|
676
676
|
sign: float = 1.0) -> tuple[np.ndarray, np.ndarray]:
|
|
677
|
-
logger.info(f'Searching around β = {target_k0:.2f} rad/m')
|
|
677
|
+
logger.info(f'Searching around β = {target_k0:.2f} rad/m with ARPACK')
|
|
678
678
|
sigma = sign*(target_k0**2)
|
|
679
679
|
eigen_values, eigen_modes = eigs(A, k=nmodes, M=B, sigma=sigma, which=which)
|
|
680
680
|
return eigen_values, eigen_modes
|
|
@@ -698,7 +698,7 @@ class SmartARPACK_BMA(EigSolver):
|
|
|
698
698
|
which: str = 'LM',
|
|
699
699
|
sign: float = 1.) -> tuple[np.ndarray, np.ndarray]:
|
|
700
700
|
|
|
701
|
-
logger.info(f'Searching around β = {target_k0:.2f} rad/m')
|
|
701
|
+
logger.info(f'Searching around β = {target_k0:.2f} rad/m with SmartARPACK (BMA)')
|
|
702
702
|
qs = np.geomspace(1, self.search_range, self.symmetric_steps)
|
|
703
703
|
tot_eigen_values = []
|
|
704
704
|
tot_eigen_modes = []
|
|
@@ -747,7 +747,7 @@ class SmartARPACK(EigSolver):
|
|
|
747
747
|
target_k0: float = 0,
|
|
748
748
|
which: str = 'LM',
|
|
749
749
|
sign: float = 1.) -> tuple[np.ndarray, np.ndarray]:
|
|
750
|
-
logger.info(f'Searching around β = {target_k0:.2f} rad/m')
|
|
750
|
+
logger.info(f'Searching around β = {target_k0:.2f} rad/m with SmartARPACK')
|
|
751
751
|
qs = np.geomspace(1, self.search_range, self.symmetric_steps)
|
|
752
752
|
tot_eigen_values = []
|
|
753
753
|
tot_eigen_modes = []
|
|
@@ -1062,7 +1062,7 @@ class SolveRoutine:
|
|
|
1062
1062
|
if direct or A.shape[0] < 1000:
|
|
1063
1063
|
return self.solvers[EMSolver.LAPACK] # type: ignore
|
|
1064
1064
|
else:
|
|
1065
|
-
return self.solvers[EMSolver.
|
|
1065
|
+
return self.solvers[EMSolver.SMART_ARPACK_BMA] # type: ignore
|
|
1066
1066
|
|
|
1067
1067
|
def solve(self, A: csr_matrix | csr_matrix,
|
|
1068
1068
|
b: np.ndarray,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
emerge/__init__.py,sha256=
|
|
1
|
+
emerge/__init__.py,sha256=YUioR8ldVN1lYGhEP8GA_DZ5XDBpsoEczbrssVIEg3o,2642
|
|
2
2
|
emerge/__main__.py,sha256=WVf16sfrOI910QWohrQDaChZdRifMNoS6VKzCT6f3ZA,92
|
|
3
3
|
emerge/cli.py,sha256=NU1uhwuZ6i50680v3_I4kDZPTHqz74gOYK71UBhb8oE,666
|
|
4
4
|
emerge/ext.py,sha256=IBoHH5PQFj5pYMfp6r-uMpNNgbSe8c0g9x8qjBzzVmU,223
|
|
@@ -22,9 +22,9 @@ emerge/_emerge/mesher.py,sha256=fKgPb6oZe_bqp0XYfZ6UNgBfRaAS3-tjUtZX8NalJe8,1319
|
|
|
22
22
|
emerge/_emerge/periodic.py,sha256=xfdKKq3qX7iBBestnRizOzJNfXlpr9lCPkiYhfrRIR8,12013
|
|
23
23
|
emerge/_emerge/plot.py,sha256=cf1I9mj7EIUJcq8vmANlUkqoV6QqVaJaP-zlC-T9E18,8041
|
|
24
24
|
emerge/_emerge/selection.py,sha256=x8cGN93BAmO80C0gn6feWcW126vorscsZVzhreTOLxs,21298
|
|
25
|
-
emerge/_emerge/simmodel.py,sha256=
|
|
25
|
+
emerge/_emerge/simmodel.py,sha256=v1cTMuyknJ5yvd6-AyjWFTd4BdYp31laNa0N8jv04QQ,19743
|
|
26
26
|
emerge/_emerge/simulation_data.py,sha256=r9-9lpLeA1Z5HU3jDVOXV1H80GVawnXL5K81_dvmlE4,14506
|
|
27
|
-
emerge/_emerge/solver.py,sha256=
|
|
27
|
+
emerge/_emerge/solver.py,sha256=77qhdRBdZJCneGYEQXkqWvY7btNDrebSJ4Vo124L-ak,48604
|
|
28
28
|
emerge/_emerge/system.py,sha256=p4HNz7d_LMRNE9Gk75vVdFecDH2iN_groAM9u-yQTpk,1618
|
|
29
29
|
emerge/_emerge/elements/__init__.py,sha256=I3n9aic6lJW-oGeqTEZ-Fpxvyl2i-WqsHdnrM3v1oB8,799
|
|
30
30
|
emerge/_emerge/elements/femdata.py,sha256=3rFVz1-PLtqxnDFvTH1Q9dA98lO5VyjcFKecCJCwfQ4,8020
|
|
@@ -32,14 +32,14 @@ emerge/_emerge/elements/index_interp.py,sha256=DlDy2KrhM5QsF6jYQIl4BJndr9F9wnjFM
|
|
|
32
32
|
emerge/_emerge/elements/ned2_interp.py,sha256=kMhbjS1fACa1fmhSkQTU35jS3iF63dJcFe5DHl4Xo78,32541
|
|
33
33
|
emerge/_emerge/elements/nedelec2.py,sha256=chU3Ewz7grKZtpyglj2qFJYHvBzCXFQZa1skzjfHoPo,6138
|
|
34
34
|
emerge/_emerge/elements/nedleg2.py,sha256=qVPKtJpT7UCA5dcI_mXNX7Co4tzVCvlxQv5VtsLuKN8,8468
|
|
35
|
-
emerge/_emerge/geo/__init__.py,sha256=
|
|
35
|
+
emerge/_emerge/geo/__init__.py,sha256=TQyNbiBOlSYBTKm5Tk2egBqKlqnwnNUt1sHqiYsvpWA,1142
|
|
36
36
|
emerge/_emerge/geo/horn.py,sha256=h4GzGzEkXgWaQgoBMvhFgGsqOrNRB3CJg3RBKXigCz0,4186
|
|
37
37
|
emerge/_emerge/geo/modeler.py,sha256=gbxmwXAdR7kKW_EFbkd1QPVqJWKJpnTufI7lxaqPyjU,15573
|
|
38
|
-
emerge/_emerge/geo/operations.py,sha256=
|
|
39
|
-
emerge/_emerge/geo/pcb.py,sha256=
|
|
38
|
+
emerge/_emerge/geo/operations.py,sha256=7u3KNa7QbFq358m7FjBX1J6b3APPkzMXTjYn7f6qfpM,12004
|
|
39
|
+
emerge/_emerge/geo/pcb.py,sha256=MmY-A-Xnd85aQw6ouOnsZKcui_kH86fw4l0GoR4qQu0,53442
|
|
40
40
|
emerge/_emerge/geo/pmlbox.py,sha256=TNjuyPtuqrAU5Yl8GrLlievuwYf3hUKJaCEz0cXKSzo,7922
|
|
41
41
|
emerge/_emerge/geo/polybased.py,sha256=loVJRBjYCTUlti5tHwfH8iU-Inb6n2sOS2Cw4gVKid4,31917
|
|
42
|
-
emerge/_emerge/geo/shapes.py,sha256
|
|
42
|
+
emerge/_emerge/geo/shapes.py,sha256=-ct-TJh69oj5fqJcQql4pNk3acJWTIQzYOQeAFXDfWk,23319
|
|
43
43
|
emerge/_emerge/geo/step.py,sha256=XcAiEN8W4umNmZdYmrGHX_aJUuiMgc6vgT-UIk8Gbqc,2689
|
|
44
44
|
emerge/_emerge/geo/pcb_tools/calculator.py,sha256=eGYUXdXmHUJCPlfJyY96S87wjeAVFG-e4sPOwbYj0eA,832
|
|
45
45
|
emerge/_emerge/geo/pcb_tools/macro.py,sha256=0g-0anOFyxrEkFobiSu0cwWFRQ32xB8Az24mmwo0z6M,2992
|
|
@@ -51,8 +51,8 @@ emerge/_emerge/physics/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3
|
|
|
51
51
|
emerge/_emerge/physics/microwave/__init__.py,sha256=QHeILGYWmvbfLl1o9wrTiWLm0evfXDgS0JiikUoMTts,28
|
|
52
52
|
emerge/_emerge/physics/microwave/adaptive_freq.py,sha256=aWhijhCVAbnuwkru-I1AaRdY20uyozf6OWRIh9r2ijg,9786
|
|
53
53
|
emerge/_emerge/physics/microwave/microwave_3d.py,sha256=5P8yyr6e6hFHBS1JAFHq8gsU1CxFG1LTelKVggv7AjY,42007
|
|
54
|
-
emerge/_emerge/physics/microwave/microwave_bc.py,sha256
|
|
55
|
-
emerge/_emerge/physics/microwave/microwave_data.py,sha256=
|
|
54
|
+
emerge/_emerge/physics/microwave/microwave_bc.py,sha256=itUDUVGPda_qdHyl45PVsc2OSKgjDwHHgmwYflN4l5Y,42316
|
|
55
|
+
emerge/_emerge/physics/microwave/microwave_data.py,sha256=cgm3i5-MbB6x_7znxAeDw2IpOPwP9cue0vWI68udwcM,47386
|
|
56
56
|
emerge/_emerge/physics/microwave/periodic.py,sha256=wYSUgLFVtCLqSG3EDKoCDRU93iPUzBdXzVRdHTRmbpI,3000
|
|
57
57
|
emerge/_emerge/physics/microwave/port_functions.py,sha256=aVU__AkVk8b1kH2J_oDLF5iNReCxC9nzCtesFSSSSQo,2112
|
|
58
58
|
emerge/_emerge/physics/microwave/sc.py,sha256=WZvoPhmHkfEv619RhmN09sXDBV0ryTqybwErA8Rc7lU,4735
|
|
@@ -70,7 +70,7 @@ emerge/_emerge/plot/display.py,sha256=TQLlKb-LkaG5ZOSLfxp9KXPlZPRFTxNj1LhVQ-Lp1-
|
|
|
70
70
|
emerge/_emerge/plot/simple_plots.py,sha256=q3IuoW4qrp5xv2S3vsVgATdE1QajWmA5_59Ma7I6GA0,24433
|
|
71
71
|
emerge/_emerge/plot/matplotlib/mpldisplay.py,sha256=szKafDrgdAW5Nyc5UOHuJC87n0WGkXYackOVv182TDQ,8671
|
|
72
72
|
emerge/_emerge/plot/pyvista/__init__.py,sha256=CPclatEu6mFnJZzCQk09g6T6Fh20WTbiLAJGSwAnPXU,30
|
|
73
|
-
emerge/_emerge/plot/pyvista/display.py,sha256=
|
|
73
|
+
emerge/_emerge/plot/pyvista/display.py,sha256=5IYVtT8ZwFu1NRwwzrzoY_FmPwjeRAfsQbg9NK383zE,37098
|
|
74
74
|
emerge/_emerge/plot/pyvista/display_settings.py,sha256=K2OhzKqeFzMXlEfZ5F4CQ9sN3l7nOgVjLplZBuMPjvE,899
|
|
75
75
|
emerge/_emerge/projects/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
76
76
|
emerge/_emerge/projects/_gen_base.txt,sha256=DqQz36PZg6v1ovQjHvPjd0t4AIbmikZdb9dmrNYsK3w,598
|
|
@@ -78,8 +78,8 @@ emerge/_emerge/projects/_load_base.txt,sha256=94o0eSWoDKlNR336EmhpG_S5syQHIUPHQx
|
|
|
78
78
|
emerge/_emerge/projects/generate_project.py,sha256=TNw-0SpLc82MBq0bd9hB_yqvBZCgmuPonCBsHTp91uk,1450
|
|
79
79
|
emerge/_emerge/solve_interfaces/cudss_interface.py,sha256=-SjiTNIyE7iJ8Bm14Cva5e2lpJDgfiS2Mvz1Bgy-UL4,9688
|
|
80
80
|
emerge/_emerge/solve_interfaces/pardiso_interface.py,sha256=iVFxToMmIzhj3hcAP-O_MDHKz82ePFIHY1us11kzUBU,15305
|
|
81
|
-
emerge-0.6.
|
|
82
|
-
emerge-0.6.
|
|
83
|
-
emerge-0.6.
|
|
84
|
-
emerge-0.6.
|
|
85
|
-
emerge-0.6.
|
|
81
|
+
emerge-0.6.7.dist-info/METADATA,sha256=J3r6jeI0a4A9x5fzG1t-h1ZL28y1SJizCz17i0Hwdrk,3304
|
|
82
|
+
emerge-0.6.7.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
83
|
+
emerge-0.6.7.dist-info/entry_points.txt,sha256=8rFvAXticpKg4OTC8JEvAksnduW72KIEskCGG9XnFf8,43
|
|
84
|
+
emerge-0.6.7.dist-info/licenses/LICENSE,sha256=SuHm9Fw32RI6tylP2YCyTPITMwpueazVUZwUMFRE_zk,17856
|
|
85
|
+
emerge-0.6.7.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|