emerge 0.5.1__py3-none-any.whl → 0.5.2__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/_emerge/bc.py +11 -8
- emerge/_emerge/cs.py +2 -2
- emerge/_emerge/elements/femdata.py +14 -14
- emerge/_emerge/elements/index_interp.py +1 -1
- emerge/_emerge/elements/ned2_interp.py +1 -1
- emerge/_emerge/elements/nedelec2.py +4 -4
- emerge/_emerge/elements/nedleg2.py +9 -9
- emerge/_emerge/geo/horn.py +1 -1
- emerge/_emerge/geo/modeler.py +18 -19
- emerge/_emerge/geo/operations.py +13 -10
- emerge/_emerge/geo/pcb.py +70 -69
- emerge/_emerge/geo/pcb_tools/macro.py +14 -13
- emerge/_emerge/geo/pmlbox.py +1 -1
- emerge/_emerge/geometry.py +46 -32
- emerge/_emerge/logsettings.py +3 -3
- emerge/_emerge/material.py +11 -11
- emerge/_emerge/mesh3d.py +81 -59
- emerge/_emerge/mesher.py +26 -21
- emerge/_emerge/mth/pairing.py +2 -2
- emerge/_emerge/periodic.py +34 -31
- emerge/_emerge/physics/microwave/adaptive_freq.py +14 -11
- emerge/_emerge/physics/microwave/assembly/assembler.py +61 -57
- emerge/_emerge/physics/microwave/assembly/generalized_eigen.py +43 -8
- emerge/_emerge/physics/microwave/assembly/robinbc.py +5 -5
- emerge/_emerge/physics/microwave/microwave_3d.py +40 -20
- emerge/_emerge/physics/microwave/microwave_bc.py +114 -95
- emerge/_emerge/physics/microwave/microwave_data.py +33 -33
- emerge/_emerge/physics/microwave/simjob.py +12 -12
- emerge/_emerge/physics/microwave/sparam.py +12 -12
- emerge/_emerge/physics/microwave/touchstone.py +1 -1
- emerge/_emerge/plot/display.py +12 -6
- emerge/_emerge/plot/pyvista/display.py +44 -39
- emerge/_emerge/plot/pyvista/display_settings.py +1 -1
- emerge/_emerge/plot/simple_plots.py +15 -15
- emerge/_emerge/selection.py +35 -39
- emerge/_emerge/simmodel.py +29 -39
- emerge/_emerge/simulation_data.py +19 -14
- emerge/_emerge/solve_interfaces/pardiso_interface.py +24 -18
- emerge/_emerge/solver.py +52 -52
- emerge/lib.py +243 -243
- {emerge-0.5.1.dist-info → emerge-0.5.2.dist-info}/METADATA +1 -1
- emerge-0.5.2.dist-info/RECORD +81 -0
- emerge/_emerge/plot/grapher.py +0 -93
- emerge-0.5.1.dist-info/RECORD +0 -82
- {emerge-0.5.1.dist-info → emerge-0.5.2.dist-info}/WHEEL +0 -0
- {emerge-0.5.1.dist-info → emerge-0.5.2.dist-info}/entry_points.txt +0 -0
- {emerge-0.5.1.dist-info → emerge-0.5.2.dist-info}/licenses/LICENSE +0 -0
|
@@ -17,39 +17,39 @@
|
|
|
17
17
|
|
|
18
18
|
import numpy as np
|
|
19
19
|
import os
|
|
20
|
-
from scipy.sparse import csr_matrix, save_npz, load_npz
|
|
20
|
+
from scipy.sparse import csr_matrix, save_npz, load_npz # type: ignore
|
|
21
21
|
from ...solver import SolveReport
|
|
22
22
|
|
|
23
23
|
class SimJob:
|
|
24
24
|
|
|
25
25
|
def __init__(self,
|
|
26
26
|
A: csr_matrix,
|
|
27
|
-
b: np.ndarray,
|
|
27
|
+
b: np.ndarray | None,
|
|
28
28
|
freq: float,
|
|
29
29
|
cache_factorization: bool,
|
|
30
30
|
B: csr_matrix = None
|
|
31
31
|
):
|
|
32
32
|
|
|
33
33
|
self.A: csr_matrix = A
|
|
34
|
-
self.B: csr_matrix = B
|
|
35
|
-
self.b: np.ndarray = b
|
|
36
|
-
self.P: csr_matrix = None
|
|
37
|
-
self.Pd: csr_matrix = None
|
|
34
|
+
self.B: csr_matrix | None = B
|
|
35
|
+
self.b: np.ndarray | None = b
|
|
36
|
+
self.P: csr_matrix | None= None
|
|
37
|
+
self.Pd: csr_matrix | None = None
|
|
38
38
|
self.has_periodic: bool = False
|
|
39
39
|
|
|
40
40
|
self.freq: float = freq
|
|
41
41
|
self.k0: float = 2*np.pi*freq/299792458
|
|
42
42
|
self.cache_factorization: bool = cache_factorization
|
|
43
43
|
self._fields: dict[int, np.ndarray] = dict()
|
|
44
|
-
self.port_vectors: dict = None
|
|
45
|
-
self.solve_ids = None
|
|
44
|
+
self.port_vectors: dict | None = None
|
|
45
|
+
self.solve_ids: np.ndarray | None = None
|
|
46
46
|
|
|
47
|
-
self.store_limit = None
|
|
48
|
-
self.relative_path = None
|
|
49
|
-
self._store_location = {}
|
|
47
|
+
self.store_limit: int | None = None
|
|
48
|
+
self.relative_path: str | None = None
|
|
49
|
+
self._store_location: dict = {}
|
|
50
50
|
self._stored: bool = False
|
|
51
51
|
|
|
52
|
-
self._active_port: int =
|
|
52
|
+
self._active_port: int = -1
|
|
53
53
|
self.reports: list[SolveReport] = []
|
|
54
54
|
self.id: int = -1
|
|
55
55
|
self.store_if_needed()
|
|
@@ -15,14 +15,14 @@
|
|
|
15
15
|
# along with this program; if not, see
|
|
16
16
|
# <https://www.gnu.org/licenses/>.
|
|
17
17
|
|
|
18
|
-
from .microwave_bc import
|
|
18
|
+
from .microwave_bc import PortBC
|
|
19
19
|
from ...mth.integrals import surface_integral
|
|
20
20
|
import numpy as np
|
|
21
21
|
from typing import Callable
|
|
22
22
|
|
|
23
23
|
def sparam_waveport(nodes: np.ndarray,
|
|
24
24
|
tri_vertices: np.ndarray,
|
|
25
|
-
bc:
|
|
25
|
+
bc: PortBC,
|
|
26
26
|
freq: float,
|
|
27
27
|
fieldf: Callable,
|
|
28
28
|
ndpts: int = 4):
|
|
@@ -62,18 +62,18 @@ def sparam_waveport(nodes: np.ndarray,
|
|
|
62
62
|
Ex2, Ey2, Ez2 = modef_c(x,y,z)
|
|
63
63
|
return Ex1*Ex2 + Ey1*Ey2 + Ez1*Ez2
|
|
64
64
|
|
|
65
|
-
mode_dot_field = surface_integral(nodes, tri_vertices, inproduct1,
|
|
66
|
-
norm = surface_integral(nodes, tri_vertices, inproduct2,
|
|
65
|
+
mode_dot_field = surface_integral(nodes, tri_vertices, inproduct1, gq_order=ndpts)
|
|
66
|
+
norm = surface_integral(nodes, tri_vertices, inproduct2, gq_order=ndpts)
|
|
67
67
|
|
|
68
68
|
svec = mode_dot_field/norm
|
|
69
69
|
return svec
|
|
70
70
|
|
|
71
71
|
def sparam_mode_power(nodes: np.ndarray,
|
|
72
72
|
tri_vertices: np.ndarray,
|
|
73
|
-
bc:
|
|
73
|
+
bc: PortBC,
|
|
74
74
|
k0: float,
|
|
75
75
|
const: np.ndarray,
|
|
76
|
-
|
|
76
|
+
gq_order: int = 4):
|
|
77
77
|
''' Compute the S-parameters assuming a wave port mode
|
|
78
78
|
|
|
79
79
|
Arguments:
|
|
@@ -83,7 +83,7 @@ def sparam_mode_power(nodes: np.ndarray,
|
|
|
83
83
|
bc: RobinBC = The port boundary condition object
|
|
84
84
|
freq: float = The frequency at which to do the calculation
|
|
85
85
|
fielf: Callable = The interpolation fuction that computes the E-field from the simulation
|
|
86
|
-
|
|
86
|
+
gq_order: int = 4 the Gauss-Quadrature order (default = 4)
|
|
87
87
|
'''
|
|
88
88
|
|
|
89
89
|
def modef(x, y, z):
|
|
@@ -94,17 +94,17 @@ def sparam_mode_power(nodes: np.ndarray,
|
|
|
94
94
|
Ex2, Ey2, Ez2 = np.conj(modef(x,y,z))
|
|
95
95
|
return (Ex1*Ex2 + Ey1*Ey2 + Ez1*Ez2)/(2*bc.Zmode(k0))
|
|
96
96
|
|
|
97
|
-
norm = surface_integral(nodes, tri_vertices, inproduct2, const, gq_order=
|
|
97
|
+
norm = surface_integral(nodes, tri_vertices, inproduct2, const, gq_order=gq_order)
|
|
98
98
|
|
|
99
99
|
return norm
|
|
100
100
|
|
|
101
101
|
def sparam_field_power(nodes: np.ndarray,
|
|
102
102
|
tri_vertices: np.ndarray,
|
|
103
|
-
bc:
|
|
103
|
+
bc: PortBC,
|
|
104
104
|
k0: float,
|
|
105
105
|
fieldf: Callable,
|
|
106
106
|
const: np.ndarray,
|
|
107
|
-
|
|
107
|
+
gq_order: int = 4) -> complex:
|
|
108
108
|
''' Compute the S-parameters assuming a wave port mode
|
|
109
109
|
|
|
110
110
|
Arguments:
|
|
@@ -114,7 +114,7 @@ def sparam_field_power(nodes: np.ndarray,
|
|
|
114
114
|
bc: RobinBC = The port boundary condition object
|
|
115
115
|
freq: float = The frequency at which to do the calculation
|
|
116
116
|
fielf: Callable = The interpolation fuction that computes the E-field from the simulation
|
|
117
|
-
|
|
117
|
+
gq_order: int = 4 the Gauss-Quadrature order (default = 4)
|
|
118
118
|
'''
|
|
119
119
|
|
|
120
120
|
def modef(x, y, z):
|
|
@@ -132,7 +132,7 @@ def sparam_field_power(nodes: np.ndarray,
|
|
|
132
132
|
Ex2, Ey2, Ez2 = np.conj(modef(x,y,z))
|
|
133
133
|
return (Ex1*Ex2 + Ey1*Ey2 + Ez1*Ez2) / (2*bc.Zmode(k0))
|
|
134
134
|
|
|
135
|
-
mode_dot_field = surface_integral(nodes, tri_vertices, inproduct1, const, gq_order=
|
|
135
|
+
mode_dot_field = surface_integral(nodes, tri_vertices, inproduct1, const, gq_order=gq_order)
|
|
136
136
|
|
|
137
137
|
svec = mode_dot_field
|
|
138
138
|
return svec
|
|
@@ -31,7 +31,7 @@ def generate_touchstone(filename: str,
|
|
|
31
31
|
freq: np.ndarray,
|
|
32
32
|
Smat: np.ndarray,
|
|
33
33
|
data_format: Literal['RI','MA','DB'],
|
|
34
|
-
custom_comments: list[str] = None,
|
|
34
|
+
custom_comments: list[str] | None = None,
|
|
35
35
|
funit: Literal['HZ','KHZ','MHZ','GHZ'] = 'GHZ') -> None:
|
|
36
36
|
"""
|
|
37
37
|
Export S-parameter data to a Touchstone file
|
emerge/_emerge/plot/display.py
CHANGED
|
@@ -18,7 +18,7 @@ class BaseDisplay:
|
|
|
18
18
|
def show(self):
|
|
19
19
|
raise NotImplementedError('This method is not implemented')
|
|
20
20
|
|
|
21
|
-
def add_object(self, obj: GeoObject | Selection
|
|
21
|
+
def add_object(self, obj: GeoObject | Selection,*args, **kwargs):
|
|
22
22
|
""" Adds an object to the display
|
|
23
23
|
|
|
24
24
|
Keyword arguments
|
|
@@ -352,14 +352,20 @@ class BaseDisplay:
|
|
|
352
352
|
def add_scatter(self, xs: np.ndarray, ys: np.ndarray, zs: np.ndarray):
|
|
353
353
|
raise NotImplementedError('This method is not implemented')
|
|
354
354
|
|
|
355
|
-
def add_portmode(self, port: PortBC,
|
|
356
|
-
|
|
355
|
+
def add_portmode(self, port: PortBC,
|
|
356
|
+
Npoints: int = 10,
|
|
357
|
+
dv=(0,0,0),
|
|
358
|
+
XYZ=None,
|
|
359
|
+
field: Literal['E','H'] = 'E',
|
|
360
|
+
k0: float | None = None,
|
|
361
|
+
mode_number: int | None = None):
|
|
357
362
|
raise NotImplementedError('This method is not implemented')
|
|
358
363
|
|
|
359
364
|
def add_quiver(self, x: np.ndarray, y: np.ndarray, z: np.ndarray,
|
|
360
365
|
dx: np.ndarray, dy: np.ndarray, dz: np.ndarray,
|
|
361
366
|
scale: float = 1,
|
|
362
|
-
|
|
367
|
+
color: tuple[float, float, float] | None = None,
|
|
368
|
+
scalemode: Literal['lin','log'] = 'lin') -> None:
|
|
363
369
|
|
|
364
370
|
raise NotImplementedError('This method is not implemented')
|
|
365
371
|
|
|
@@ -370,10 +376,10 @@ class BaseDisplay:
|
|
|
370
376
|
field: np.ndarray,
|
|
371
377
|
scale: Literal['lin','log','symlog'] = 'lin',
|
|
372
378
|
cmap: cmap_names = 'coolwarm',
|
|
373
|
-
clim: tuple[float, float] = None,
|
|
379
|
+
clim: tuple[float, float] | None = None,
|
|
374
380
|
opacity: float = 1.0,
|
|
375
381
|
symmetrize: bool = True,
|
|
376
|
-
|
|
382
|
+
_fieldname: str | None = None,
|
|
377
383
|
**kwargs,):
|
|
378
384
|
"""Add a surface plot to the display
|
|
379
385
|
The X,Y,Z coordinates must be a 2D grid of data points. The field must be a real field with the same size.
|
|
@@ -22,7 +22,7 @@ from ...selection import FaceSelection, DomainSelection, EdgeSelection, Selectio
|
|
|
22
22
|
from ...physics.microwave.microwave_bc import PortBC, ModalPort
|
|
23
23
|
import numpy as np
|
|
24
24
|
import pyvista as pv
|
|
25
|
-
from typing import Iterable, Literal, Callable
|
|
25
|
+
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
|
|
@@ -155,7 +155,7 @@ def _select(obj: GeoObject | Selection) -> Selection:
|
|
|
155
155
|
return obj.select
|
|
156
156
|
return obj
|
|
157
157
|
|
|
158
|
-
def _merge(lst:
|
|
158
|
+
def _merge(lst: Iterable[GeoObject | Selection]) -> Selection:
|
|
159
159
|
selections = [_select(item) for item in lst]
|
|
160
160
|
dim = selections[0].dim
|
|
161
161
|
all_tags = []
|
|
@@ -168,6 +168,8 @@ def _merge(lst: list[GeoObject | Selection]) -> Selection:
|
|
|
168
168
|
return FaceSelection(all_tags)
|
|
169
169
|
elif dim==3:
|
|
170
170
|
return DomainSelection(all_tags)
|
|
171
|
+
else:
|
|
172
|
+
return Selection(all_tags)
|
|
171
173
|
|
|
172
174
|
class _AnimObject:
|
|
173
175
|
""" A private class containing the required information for plot items in a view
|
|
@@ -199,7 +201,7 @@ class PVDisplay(BaseDisplay):
|
|
|
199
201
|
self._stop: bool = False
|
|
200
202
|
self._objs: list[_AnimObject] = []
|
|
201
203
|
self._do_animate: bool = False
|
|
202
|
-
self._Nsteps: int
|
|
204
|
+
self._Nsteps: int = 0
|
|
203
205
|
self._fps: int = 25
|
|
204
206
|
self._ruler: ScreenRuler = ScreenRuler(self, 0.001)
|
|
205
207
|
self._selector: ScreenSelector = ScreenSelector(self)
|
|
@@ -208,10 +210,11 @@ class PVDisplay(BaseDisplay):
|
|
|
208
210
|
|
|
209
211
|
self._plot = pv.Plotter()
|
|
210
212
|
|
|
211
|
-
self._plot.add_key_event("m", self.activate_ruler)
|
|
212
|
-
self._plot.add_key_event("f", self.activate_object)
|
|
213
|
+
self._plot.add_key_event("m", self.activate_ruler) # type: ignore
|
|
214
|
+
self._plot.add_key_event("f", self.activate_object) # type: ignore
|
|
213
215
|
|
|
214
216
|
self._ctr: int = 0
|
|
217
|
+
|
|
215
218
|
def activate_ruler(self):
|
|
216
219
|
self._plot.disable_picking()
|
|
217
220
|
self._selector.turn_off()
|
|
@@ -310,7 +313,7 @@ class PVDisplay(BaseDisplay):
|
|
|
310
313
|
points = self._mesh.nodes.T
|
|
311
314
|
return pv.UnstructuredGrid(cells, celltypes, points)
|
|
312
315
|
|
|
313
|
-
def mesh(self, obj: GeoObject | Selection | Iterable) -> pv.UnstructuredGrid:
|
|
316
|
+
def mesh(self, obj: GeoObject | Selection | Iterable) -> pv.UnstructuredGrid | None:
|
|
314
317
|
if isinstance(obj, Iterable):
|
|
315
318
|
obj = _merge(obj)
|
|
316
319
|
else:
|
|
@@ -320,11 +323,13 @@ class PVDisplay(BaseDisplay):
|
|
|
320
323
|
return self.mesh_volume(obj)
|
|
321
324
|
elif isinstance(obj, FaceSelection):
|
|
322
325
|
return self.mesh_surface(obj)
|
|
326
|
+
else:
|
|
327
|
+
return None
|
|
323
328
|
|
|
324
329
|
## OBLIGATORY METHODS
|
|
325
|
-
def add_object(self, obj: GeoObject | Selection
|
|
326
|
-
kwargs = setdefault(kwargs, color=obj.color_rgb, opacity=obj.opacity, silhouette=True)
|
|
327
|
-
self._plot.add_mesh(self.mesh(obj),
|
|
330
|
+
def add_object(self, obj: GeoObject | Selection, *args, **kwargs):
|
|
331
|
+
kwargs = setdefault(kwargs, color=obj.color_rgb, opacity=obj.opacity, silhouette=True, pickable=True)
|
|
332
|
+
self._plot.add_mesh(self.mesh(obj), *args, **kwargs)
|
|
328
333
|
|
|
329
334
|
def add_scatter(self, xs: np.ndarray, ys: np.ndarray, zs: np.ndarray):
|
|
330
335
|
"""Adds a scatter point cloud
|
|
@@ -342,8 +347,8 @@ class PVDisplay(BaseDisplay):
|
|
|
342
347
|
dv=(0,0,0),
|
|
343
348
|
XYZ=None,
|
|
344
349
|
field: Literal['E','H'] = 'E',
|
|
345
|
-
k0: float = None,
|
|
346
|
-
mode_number: int = None) ->
|
|
350
|
+
k0: float | None = None,
|
|
351
|
+
mode_number: int | None = None) -> None:
|
|
347
352
|
|
|
348
353
|
if XYZ:
|
|
349
354
|
X,Y,Z = XYZ
|
|
@@ -408,10 +413,10 @@ class PVDisplay(BaseDisplay):
|
|
|
408
413
|
field: np.ndarray,
|
|
409
414
|
scale: Literal['lin','log','symlog'] = 'lin',
|
|
410
415
|
cmap: cmap_names = 'coolwarm',
|
|
411
|
-
clim: tuple[float, float] = None,
|
|
416
|
+
clim: tuple[float, float] | None = None,
|
|
412
417
|
opacity: float = 1.0,
|
|
413
418
|
symmetrize: bool = True,
|
|
414
|
-
_fieldname: str = None,
|
|
419
|
+
_fieldname: str | None = None,
|
|
415
420
|
**kwargs,):
|
|
416
421
|
"""Add a surface plot to the display
|
|
417
422
|
The X,Y,Z coordinates must be a 2D grid of data points. The field must be a real field with the same size.
|
|
@@ -460,11 +465,11 @@ class PVDisplay(BaseDisplay):
|
|
|
460
465
|
kwargs = setdefault(kwargs, cmap=cmap, clim=clim, opacity=opacity, pickable=False, multi_colors=True)
|
|
461
466
|
actor = self._plot.add_mesh(grid, scalars=name, **kwargs)
|
|
462
467
|
|
|
463
|
-
if self.
|
|
468
|
+
if self._do_animate:
|
|
464
469
|
def on_update(obj: _AnimObject, phi: complex):
|
|
465
470
|
field = obj.T(np.real(obj.field*phi))
|
|
466
471
|
obj.grid['anim'] = field
|
|
467
|
-
self._objs.append(_AnimObject(field_flat, T, grid, actor, on_update))
|
|
472
|
+
self._objs.append(_AnimObject(field_flat, T, grid, actor, on_update)) # type: ignore
|
|
468
473
|
|
|
469
474
|
|
|
470
475
|
def add_title(self, title: str) -> None:
|
|
@@ -481,14 +486,14 @@ class PVDisplay(BaseDisplay):
|
|
|
481
486
|
def add_text(self, text: str,
|
|
482
487
|
color: str = 'black',
|
|
483
488
|
position: Literal['lower_left', 'lower_right', 'upper_left', 'upper_right', 'lower_edge', 'upper_edge', 'right_edge', 'left_edge']='upper_right',
|
|
484
|
-
abs_position: tuple[float, float, float] = None):
|
|
489
|
+
abs_position: tuple[float, float, float] | None = None):
|
|
485
490
|
viewport = False
|
|
486
491
|
if abs_position is not None:
|
|
487
|
-
|
|
492
|
+
final_position = abs_position
|
|
488
493
|
viewport = True
|
|
489
494
|
self._plot.add_text(
|
|
490
495
|
text,
|
|
491
|
-
position=
|
|
496
|
+
position=final_position,
|
|
492
497
|
color=color,
|
|
493
498
|
font_size=18,
|
|
494
499
|
viewport=viewport)
|
|
@@ -496,7 +501,7 @@ class PVDisplay(BaseDisplay):
|
|
|
496
501
|
def add_quiver(self, x: np.ndarray, y: np.ndarray, z: np.ndarray,
|
|
497
502
|
dx: np.ndarray, dy: np.ndarray, dz: np.ndarray,
|
|
498
503
|
scale: float = 1,
|
|
499
|
-
color: tuple[float, float, float] = None,
|
|
504
|
+
color: tuple[float, float, float] | None = None,
|
|
500
505
|
scalemode: Literal['lin','log'] = 'lin'):
|
|
501
506
|
"""Add a quiver plot to the display
|
|
502
507
|
|
|
@@ -562,18 +567,18 @@ class PVDisplay(BaseDisplay):
|
|
|
562
567
|
grid = pv.StructuredGrid(X,Y,Z)
|
|
563
568
|
field = V.flatten(order='F')
|
|
564
569
|
grid['anim'] = np.real(field)
|
|
565
|
-
levels = np.linspace(vmin, vmax, Nlevels)
|
|
570
|
+
levels = list(np.linspace(vmin, vmax, Nlevels))
|
|
566
571
|
contour = grid.contour(isosurfaces=levels)
|
|
567
572
|
actor = self._plot.add_mesh(contour, opacity=0.25, cmap=cmap, pickable=False)
|
|
568
573
|
|
|
569
|
-
if self.
|
|
574
|
+
if self._do_animate:
|
|
570
575
|
def on_update(obj: _AnimObject, phi: complex):
|
|
571
576
|
new_vals = np.real(obj.field * phi)
|
|
572
577
|
obj.grid['anim'] = new_vals
|
|
573
578
|
new_contour = obj.grid.contour(isosurfaces=levels)
|
|
574
|
-
obj.actor.GetMapper().SetInputData(new_contour)
|
|
579
|
+
obj.actor.GetMapper().SetInputData(new_contour) # type: ignore
|
|
575
580
|
|
|
576
|
-
self._objs.append(_AnimObject(field, lambda x: x, grid, actor, on_update))
|
|
581
|
+
self._objs.append(_AnimObject(field, lambda x: x, grid, actor, on_update)) # type: ignore
|
|
577
582
|
|
|
578
583
|
def _add_aux_items(self) -> None:
|
|
579
584
|
saved_camera = {
|
|
@@ -591,8 +596,8 @@ class PVDisplay(BaseDisplay):
|
|
|
591
596
|
plane = pv.Plane(
|
|
592
597
|
center=(0, 0, 0),
|
|
593
598
|
direction=(1, 0, 0), # normal vector pointing along +X
|
|
594
|
-
i_size=length,
|
|
595
|
-
j_size=length,
|
|
599
|
+
i_size=length, # type: ignore
|
|
600
|
+
j_size=length, # type: ignore
|
|
596
601
|
i_resolution=1,
|
|
597
602
|
j_resolution=1
|
|
598
603
|
)
|
|
@@ -617,8 +622,8 @@ class PVDisplay(BaseDisplay):
|
|
|
617
622
|
plane = pv.Plane(
|
|
618
623
|
center=(0, 0, 0),
|
|
619
624
|
direction=(0, 1, 0), # normal vector pointing along +X
|
|
620
|
-
i_size=length,
|
|
621
|
-
j_size=length,
|
|
625
|
+
i_size=length, # type: ignore
|
|
626
|
+
j_size=length, # type: ignore
|
|
622
627
|
i_resolution=1,
|
|
623
628
|
j_resolution=1
|
|
624
629
|
)
|
|
@@ -642,8 +647,8 @@ class PVDisplay(BaseDisplay):
|
|
|
642
647
|
plane = pv.Plane(
|
|
643
648
|
center=(0, 0, 0),
|
|
644
649
|
direction=(0, 0, 1), # normal vector pointing along +X
|
|
645
|
-
i_size=length,
|
|
646
|
-
j_size=length,
|
|
650
|
+
i_size=length, # type: ignore
|
|
651
|
+
j_size=length, # type: ignore
|
|
647
652
|
i_resolution=1,
|
|
648
653
|
j_resolution=1
|
|
649
654
|
)
|
|
@@ -776,11 +781,11 @@ class PVDisplay(BaseDisplay):
|
|
|
776
781
|
|
|
777
782
|
if self.set.add_light:
|
|
778
783
|
light = pv.Light()
|
|
779
|
-
light.set_direction_angle(*self.set.light_angle)
|
|
784
|
+
light.set_direction_angle(*self.set.light_angle) # type: ignore
|
|
780
785
|
self._plot.add_light(light)
|
|
781
786
|
|
|
782
|
-
self._plot.set_background(self.set.background_bottom, top=self.set.background_top)
|
|
783
|
-
self._plot.add_axes()
|
|
787
|
+
self._plot.set_background(self.set.background_bottom, top=self.set.background_top) # type: ignore
|
|
788
|
+
self._plot.add_axes() # type: ignore
|
|
784
789
|
|
|
785
790
|
self._plot.camera.position = saved_camera["position"]
|
|
786
791
|
self._plot.camera.focal_point = saved_camera["focal_point"]
|
|
@@ -837,7 +842,7 @@ class ScreenSelector:
|
|
|
837
842
|
celltypes = np.full(ntris, fill_value=pv.CellType.TRIANGLE, dtype=np.uint8)
|
|
838
843
|
points = self.disp._mesh.nodes.T
|
|
839
844
|
grid = pv.UnstructuredGrid(cells, celltypes, points)
|
|
840
|
-
grid._tag = key
|
|
845
|
+
grid._tag = key # type: ignore
|
|
841
846
|
self.grids.append(grid)
|
|
842
847
|
self.surfs[key] = points[nodes,:].T
|
|
843
848
|
|
|
@@ -856,14 +861,14 @@ class ScreenSelector:
|
|
|
856
861
|
meany = np.mean(ys)
|
|
857
862
|
meanz = np.mean(zs)
|
|
858
863
|
data = (meanx, meany, meanz, min(xs), min(ys), min(zs), max(xs), max(ys), max(zs))
|
|
859
|
-
encoded = encode_data(data)
|
|
864
|
+
encoded = encode_data(data) #type: ignore
|
|
860
865
|
print(f'Face code key={key}: ', encoded)
|
|
861
866
|
|
|
862
867
|
self.disp._plot.enable_mesh_picking(callback, style='surface', left_clicking=True, use_actor=True)
|
|
863
868
|
|
|
864
869
|
def turn_off(self) -> None:
|
|
865
870
|
for actor in self.select_actors:
|
|
866
|
-
self.disp._plot.remove_actor(actor)
|
|
871
|
+
self.disp._plot.remove_actor(actor) # type: ignore
|
|
867
872
|
self.select_actors = []
|
|
868
873
|
for actor in self.original_actors:
|
|
869
874
|
if isinstance(actor, pv.Text):
|
|
@@ -876,9 +881,9 @@ class ScreenRuler:
|
|
|
876
881
|
def __init__(self, display: PVDisplay, min_length: float):
|
|
877
882
|
self.disp: PVDisplay = display
|
|
878
883
|
self.points: list[tuple] = [(0,0,0),(0,0,0)]
|
|
879
|
-
self.text: pv.Text = None
|
|
880
|
-
self.ruler = None
|
|
881
|
-
self.state = False
|
|
884
|
+
self.text: pv.Text | None = None
|
|
885
|
+
self.ruler: Any = None
|
|
886
|
+
self.state: bool = False
|
|
882
887
|
self.min_length: float = min_length
|
|
883
888
|
|
|
884
889
|
@freeze
|
|
@@ -916,7 +921,7 @@ class ScreenRuler:
|
|
|
916
921
|
|
|
917
922
|
def set_ruler(self) -> None:
|
|
918
923
|
if self.ruler is None:
|
|
919
|
-
self.ruler = self.disp._plot.add_ruler(self.points[0], self.points[1], title=f'{1000*self.dist:.2f}mm')
|
|
924
|
+
self.ruler = self.disp._plot.add_ruler(self.points[0], self.points[1], title=f'{1000*self.dist:.2f}mm') # type: ignore
|
|
920
925
|
else:
|
|
921
926
|
p1 = self.ruler.GetPositionCoordinate()
|
|
922
927
|
p2 = self.ruler.GetPosition2Coordinate()
|
|
@@ -17,7 +17,7 @@ class PVDisplaySettings:
|
|
|
17
17
|
self.show_zgrid: bool = True
|
|
18
18
|
self.grid_line_width: float = 1.0
|
|
19
19
|
self.add_light: bool = False
|
|
20
|
-
self.light_angle: float = (20
|
|
20
|
+
self.light_angle: tuple[float, float] = (20., -20.)
|
|
21
21
|
self.cast_shadows: bool = True
|
|
22
22
|
self.background_bottom: str = "#c0d2e8"
|
|
23
23
|
self.background_top: str = "#ffffff"
|
|
@@ -36,7 +36,7 @@ ggplot_styles = {
|
|
|
36
36
|
|
|
37
37
|
plt.rcParams.update(ggplot_styles)
|
|
38
38
|
|
|
39
|
-
def _gen_grid(xs: tuple, ys: tuple, N = 201) -> list[np.ndarray]:
|
|
39
|
+
def _gen_grid(xs: tuple, ys: tuple, N = 201) -> list[tuple[np.ndarray, np.ndarray]]:
|
|
40
40
|
"""Generate a grid of lines for the Smith Chart
|
|
41
41
|
|
|
42
42
|
Args:
|
|
@@ -279,18 +279,18 @@ def smith(f: np.ndarray, S: np.ndarray) -> None:
|
|
|
279
279
|
def plot_sp(f: np.ndarray, S: list[np.ndarray] | np.ndarray,
|
|
280
280
|
dblim=[-40, 5],
|
|
281
281
|
xunit="GHz",
|
|
282
|
-
levelindicator: int | float =None,
|
|
282
|
+
levelindicator: int | float | None = None,
|
|
283
283
|
noise_floor=-150,
|
|
284
|
-
fill_areas: list[tuple]= None,
|
|
285
|
-
spec_area: list[tuple[float]] = None,
|
|
284
|
+
fill_areas: list[tuple] | None = None,
|
|
285
|
+
spec_area: list[tuple[float,...]] | None = None,
|
|
286
286
|
unwrap_phase=False,
|
|
287
287
|
logx: bool = False,
|
|
288
|
-
labels: list[str] = None,
|
|
289
|
-
linestyles: list[str] = None,
|
|
290
|
-
colorcycle: list[int] = None,
|
|
291
|
-
filename: str = None,
|
|
288
|
+
labels: list[str] | None = None,
|
|
289
|
+
linestyles: list[str] | None = None,
|
|
290
|
+
colorcycle: list[int] | None = None,
|
|
291
|
+
filename: str | None = None,
|
|
292
292
|
show_plot: bool = True,
|
|
293
|
-
figdata: tuple = None) ->
|
|
293
|
+
figdata: tuple | None = None) -> tuple[plt.Figure, plt.Axes, plt.Axes]:
|
|
294
294
|
"""Plot S-parameters in dB and phase
|
|
295
295
|
|
|
296
296
|
Args:
|
|
@@ -321,7 +321,7 @@ def plot_sp(f: np.ndarray, S: list[np.ndarray] | np.ndarray,
|
|
|
321
321
|
if colorcycle is None:
|
|
322
322
|
colorcycle = [i for i, S in enumerate(S)]
|
|
323
323
|
|
|
324
|
-
unitdivider = {"MHz": 1e6, "GHz": 1e9, "kHz": 1e3}
|
|
324
|
+
unitdivider: dict[str, float] = {"MHz": 1e6, "GHz": 1e9, "kHz": 1e3}
|
|
325
325
|
fnew = f / unitdivider[xunit]
|
|
326
326
|
|
|
327
327
|
if figdata is None:
|
|
@@ -372,14 +372,14 @@ def plot_sp(f: np.ndarray, S: list[np.ndarray] | np.ndarray,
|
|
|
372
372
|
# Configure magnitude plot (ax_mag)
|
|
373
373
|
ax_mag.set_ylabel("Magnitude (dB)")
|
|
374
374
|
ax_mag.set_xlabel(f"Frequency ({xunit})")
|
|
375
|
-
ax_mag.axis([min(fnew), max(fnew), dblim[0], max(maxy*1.1,dblim[1])])
|
|
375
|
+
ax_mag.axis([min(fnew), max(fnew), dblim[0], max(maxy*1.1,dblim[1])]) # type: ignore
|
|
376
376
|
ax_mag.axhline(y=0, color="k", linewidth=1)
|
|
377
377
|
ax_mag.xaxis.set_minor_locator(tck.AutoMinorLocator(2))
|
|
378
378
|
ax_mag.yaxis.set_minor_locator(tck.AutoMinorLocator(2))
|
|
379
379
|
# Configure phase plot (ax_phase)
|
|
380
380
|
ax_phase.set_ylabel("Phase (degrees)")
|
|
381
381
|
ax_phase.set_xlabel(f"Frequency ({xunit})")
|
|
382
|
-
ax_phase.axis([min(fnew), max(fnew), minphase, maxphase])
|
|
382
|
+
ax_phase.axis([min(fnew), max(fnew), minphase, maxphase]) # type: ignore
|
|
383
383
|
ax_phase.xaxis.set_minor_locator(tck.AutoMinorLocator(2))
|
|
384
384
|
ax_phase.yaxis.set_minor_locator(tck.AutoMinorLocator(2))
|
|
385
385
|
if logx:
|
|
@@ -532,9 +532,9 @@ def plot_ff_polar(
|
|
|
532
532
|
markers = _broadcast(markers, None) if markers is not None else [None] * n_series
|
|
533
533
|
|
|
534
534
|
fig, ax = plt.subplots(subplot_kw={'projection': 'polar'})
|
|
535
|
-
ax.set_theta_zero_location(zero_location)
|
|
536
|
-
ax.set_theta_direction(-1 if clockwise else 1)
|
|
537
|
-
ax.set_rlabel_position(rlabel_angle)
|
|
535
|
+
ax.set_theta_zero_location(zero_location) # type: ignore
|
|
536
|
+
ax.set_theta_direction(-1 if clockwise else 1) # type: ignore
|
|
537
|
+
ax.set_rlabel_position(rlabel_angle) # type: ignore
|
|
538
538
|
|
|
539
539
|
for i, Ei in enumerate(E_list):
|
|
540
540
|
mag = np.abs(Ei)
|