emerge 0.5.1__py3-none-any.whl → 0.5.3__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.

Files changed (54) hide show
  1. emerge/_emerge/bc.py +14 -20
  2. emerge/_emerge/const.py +5 -0
  3. emerge/_emerge/cs.py +2 -2
  4. emerge/_emerge/elements/femdata.py +14 -14
  5. emerge/_emerge/elements/index_interp.py +1 -1
  6. emerge/_emerge/elements/ned2_interp.py +1 -1
  7. emerge/_emerge/elements/nedelec2.py +4 -4
  8. emerge/_emerge/elements/nedleg2.py +10 -10
  9. emerge/_emerge/geo/horn.py +1 -1
  10. emerge/_emerge/geo/modeler.py +18 -19
  11. emerge/_emerge/geo/operations.py +13 -10
  12. emerge/_emerge/geo/pcb.py +180 -82
  13. emerge/_emerge/geo/pcb_tools/calculator.py +2 -2
  14. emerge/_emerge/geo/pcb_tools/macro.py +14 -13
  15. emerge/_emerge/geo/pmlbox.py +1 -1
  16. emerge/_emerge/geometry.py +47 -33
  17. emerge/_emerge/logsettings.py +15 -16
  18. emerge/_emerge/material.py +15 -11
  19. emerge/_emerge/mesh3d.py +81 -59
  20. emerge/_emerge/mesher.py +26 -21
  21. emerge/_emerge/mth/integrals.py +1 -1
  22. emerge/_emerge/mth/pairing.py +2 -2
  23. emerge/_emerge/periodic.py +34 -31
  24. emerge/_emerge/physics/microwave/adaptive_freq.py +15 -16
  25. emerge/_emerge/physics/microwave/assembly/assembler.py +120 -93
  26. emerge/_emerge/physics/microwave/assembly/curlcurl.py +1 -8
  27. emerge/_emerge/physics/microwave/assembly/generalized_eigen.py +43 -8
  28. emerge/_emerge/physics/microwave/assembly/robinbc.py +5 -5
  29. emerge/_emerge/physics/microwave/microwave_3d.py +71 -44
  30. emerge/_emerge/physics/microwave/microwave_bc.py +206 -117
  31. emerge/_emerge/physics/microwave/microwave_data.py +36 -38
  32. emerge/_emerge/physics/microwave/sc.py +26 -26
  33. emerge/_emerge/physics/microwave/simjob.py +20 -15
  34. emerge/_emerge/physics/microwave/sparam.py +12 -12
  35. emerge/_emerge/physics/microwave/touchstone.py +1 -1
  36. emerge/_emerge/plot/display.py +12 -6
  37. emerge/_emerge/plot/pyvista/display.py +44 -39
  38. emerge/_emerge/plot/pyvista/display_settings.py +1 -1
  39. emerge/_emerge/plot/simple_plots.py +15 -15
  40. emerge/_emerge/selection.py +35 -39
  41. emerge/_emerge/simmodel.py +41 -47
  42. emerge/_emerge/simulation_data.py +24 -15
  43. emerge/_emerge/solve_interfaces/cudss_interface.py +238 -0
  44. emerge/_emerge/solve_interfaces/pardiso_interface.py +24 -18
  45. emerge/_emerge/solver.py +314 -136
  46. emerge/cli.py +1 -1
  47. emerge/lib.py +245 -248
  48. {emerge-0.5.1.dist-info → emerge-0.5.3.dist-info}/METADATA +5 -1
  49. emerge-0.5.3.dist-info/RECORD +83 -0
  50. emerge/_emerge/plot/grapher.py +0 -93
  51. emerge-0.5.1.dist-info/RECORD +0 -82
  52. {emerge-0.5.1.dist-info → emerge-0.5.3.dist-info}/WHEEL +0 -0
  53. {emerge-0.5.1.dist-info → emerge-0.5.3.dist-info}/entry_points.txt +0 -0
  54. {emerge-0.5.1.dist-info → emerge-0.5.3.dist-info}/licenses/LICENSE +0 -0
@@ -20,13 +20,14 @@ from ...simulation_data import BaseDataset, DataContainer
20
20
  from ...elements.femdata import FEMBasis
21
21
  from dataclasses import dataclass
22
22
  import numpy as np
23
- from typing import Literal, Any
23
+ from typing import Literal
24
24
  from loguru import logger
25
25
  from .adaptive_freq import SparamModel
26
26
  from ...cs import Axis, _parse_axis
27
27
  from ...selection import FaceSelection
28
28
  from ...geometry import GeoSurface
29
29
  from ...mesh3d import Mesh3D
30
+ from ...const import Z0, MU0, EPS0
30
31
 
31
32
  EMField = Literal[
32
33
  "er", "ur", "freq", "k0",
@@ -36,9 +37,6 @@ EMField = Literal[
36
37
  "mode", "beta",
37
38
  ]
38
39
 
39
- EPS0 = 8.854187818814e-12
40
- MU0 = 1.2566370612720e-6
41
-
42
40
  def arc_on_plane(ref_dir, normal, angle_range_deg, num_points=100):
43
41
  """
44
42
  Generate theta/phi coordinates of an arc on a plane.
@@ -128,7 +126,7 @@ def generate_ndim(
128
126
  outer_data: dict[str, list[float]],
129
127
  inner_data: list[float],
130
128
  outer_labels: tuple[str, ...]
131
- ) -> np.ndarray:
129
+ ) -> tuple[np.ndarray,...]:
132
130
  """
133
131
  Generates an N-dimensional grid of values from flattened data, and returns each axis array plus the grid.
134
132
 
@@ -231,10 +229,10 @@ class Sparam:
231
229
 
232
230
  @dataclass
233
231
  class PortProperties:
234
- port_number: int | None = None
232
+ port_number: int = -1
235
233
  k0: float | None= None
236
234
  beta: float | None = None
237
- Z0: float | None = None
235
+ Z0: float | complex | None = None
238
236
  Pout: float | None = None
239
237
  mode_number: int = 1
240
238
 
@@ -259,7 +257,7 @@ class FarfieldData:
259
257
 
260
258
  def surfplot(self,
261
259
  polarization: Literal['Ex','Ey','Ez','Etheta','Ephi','normE'],
262
- isotropic: bool = True, dB: bool = False, dBfloor: float = -30, rmax: float = None,
260
+ isotropic: bool = True, dB: bool = False, dBfloor: float = -30, rmax: float | None = None,
263
261
  offset: tuple[float, float, float] = (0,0,0)) -> tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]:
264
262
  """Returns the parameters to be used as positional arguments for the display.add_surf() function.
265
263
 
@@ -297,7 +295,7 @@ class FarfieldData:
297
295
  logger.warning('Defaulting to normE')
298
296
  F = np.sqrt(np.abs(self.E[0,:])**2 + np.abs(self.E[1,:])**2 + np.abs(self.E[2,:])**2)
299
297
  if isotropic:
300
- F = F/np.sqrt(376.730313412/(2*np.pi))
298
+ F = F/np.sqrt(Z0/(2*np.pi))
301
299
  if dB:
302
300
  F = 20*np.log10(np.clip(np.abs(F), a_min=10**(dBfloor/20), a_max = 1e9))-dBfloor
303
301
  if rmax is not None:
@@ -345,7 +343,7 @@ class EHField:
345
343
 
346
344
  @property
347
345
  def Dy(self) -> np.ndarray:
348
- return self.Et*self.er
346
+ return self.Ey*self.er
349
347
 
350
348
  @property
351
349
  def Dz(self) -> np.ndarray:
@@ -499,16 +497,16 @@ class EHField:
499
497
  Returns:
500
498
  (X,Y,Z,Field): The coordinates plus field scalar
501
499
  """
502
- field = getattr(self, field)
500
+ field_arry = getattr(self, field)
503
501
  if metric=='abs':
504
- field = np.abs(field)
502
+ field = np.abs(field_arry)
505
503
  elif metric=='real':
506
- field = field.real
504
+ field = field_arry.real
507
505
  elif metric=='imag':
508
- field = field.imag
506
+ field = field_arry.imag
509
507
  elif metric=='complex':
510
- field = field
511
- return self.x, self.y, self.z, field
508
+ field = field_arry
509
+ return self.x, self.y, self.z, field_arry
512
510
 
513
511
  class _EHSign:
514
512
  """A small class to manage the sign of field components when computing the far-field with Stratton-Chu
@@ -588,7 +586,7 @@ class MWField:
588
586
  mode_number: int,
589
587
  k0: float,
590
588
  beta: float,
591
- Z0: float,
589
+ Z0: float | complex | None,
592
590
  Pout: float) -> None:
593
591
  self.port_modes.append(PortProperties(port_number=port_number,
594
592
  mode_number=mode_number,
@@ -609,7 +607,7 @@ class MWField:
609
607
  def _field(self) -> np.ndarray:
610
608
  if self._mode_field is not None:
611
609
  return self._mode_field
612
- return sum([self.excitation[mode.port_number]*self._fields[mode.port_number] for mode in self.port_modes])
610
+ return sum([self.excitation[mode.port_number]*self._fields[mode.port_number] for mode in self.port_modes]) # type: ignore
613
611
 
614
612
  def set_field_vector(self) -> None:
615
613
  """Defines the default excitation coefficients for the current dataset"""
@@ -662,7 +660,7 @@ class MWField:
662
660
  self.Ez = Ez.reshape(shp)
663
661
 
664
662
 
665
- constants = 1/ (-1j*2*np.pi*self.freq*(self._dur*4*np.pi*1e-7) )
663
+ constants = 1/ (-1j*2*np.pi*self.freq*(self._dur*MU0) )
666
664
  Hx, Hy, Hz = self.basis.interpolate_curl(self._field, xf, yf, zf, constants)
667
665
  ids = self.basis.interpolate_index(xf, yf, zf)
668
666
  self.er = self._der[ids].reshape(shp)
@@ -678,9 +676,9 @@ class MWField:
678
676
 
679
677
  def cutplane(self,
680
678
  ds: float,
681
- x: float=None,
682
- y: float=None,
683
- z: float=None) -> EHField:
679
+ x: float | None = None,
680
+ y: float | None = None,
681
+ z: float | None = None) -> EHField:
684
682
  xb, yb, zb = self.basis.bounds
685
683
  xs = np.linspace(xb[0], xb[1], int((xb[1]-xb[0])/ds))
686
684
  ys = np.linspace(yb[0], yb[1], int((yb[1]-yb[0])/ds))
@@ -765,8 +763,8 @@ class MWField:
765
763
  faces: FaceSelection | GeoSurface,
766
764
  ang_range: tuple[float, float] = (-180, 180),
767
765
  Npoints: int = 201,
768
- origin: tuple[float, float, float] = None,
769
- syms: list[Literal['Ex','Ey','Ez', 'Hx','Hy','Hz']] = None) -> tuple[np.ndarray, np.ndarray, np.ndarray]:
766
+ origin: tuple[float, float, float] | None = None,
767
+ syms: list[Literal['Ex','Ey','Ez', 'Hx','Hy','Hz']] | None = None) -> tuple[np.ndarray, np.ndarray, np.ndarray]:
770
768
  """Compute the farfield electric and magnetic field defined by a circle.
771
769
 
772
770
  Args:
@@ -782,18 +780,18 @@ class MWField:
782
780
  tuple[np.ndarray, np.ndarray, np.ndarray]: _description_
783
781
  """
784
782
  refdir = _parse_axis(ref_direction).np
785
- plane_normal = _parse_axis(plane_normal).np
786
- theta, phi = arc_on_plane(refdir, plane_normal, ang_range, Npoints)
783
+ plane_normal_parsed = _parse_axis(plane_normal).np
784
+ theta, phi = arc_on_plane(refdir, plane_normal_parsed, ang_range, Npoints)
787
785
  E,H = self.farfield(theta, phi, faces, origin, syms = syms)
788
786
  angs = np.linspace(*ang_range, Npoints)*np.pi/180
789
787
  return angs, E ,H
790
788
 
791
789
  def farfield_3d(self,
792
790
  faces: FaceSelection | GeoSurface,
793
- thetas: np.ndarray = None,
794
- phis: np.ndarray = None,
795
- origin: tuple[float, float, float] = None,
796
- syms: list[Literal['Ex','Ey','Ez', 'Hx','Hy','Hz']] = None) -> FarfieldData:
791
+ thetas: np.ndarray | None = None,
792
+ phis: np.ndarray | None = None,
793
+ origin: tuple[float, float, float] | None = None,
794
+ syms: list[Literal['Ex','Ey','Ez', 'Hx','Hy','Hz']] | None = None) -> FarfieldData:
797
795
  """Compute the farfield in a 3D angular grid
798
796
 
799
797
  If thetas and phis are not provided, they default to a sample space of 2 degrees.
@@ -823,8 +821,8 @@ class MWField:
823
821
  def farfield(self, theta: np.ndarray,
824
822
  phi: np.ndarray,
825
823
  faces: FaceSelection | GeoSurface,
826
- origin: tuple[float, float, float] = None,
827
- syms: list[Literal['Ex','Ey','Ez', 'Hx','Hy','Hz']] = None) -> tuple[np.ndarray, np.ndarray]:
824
+ origin: tuple[float, float, float] | None = None,
825
+ syms: list[Literal['Ex','Ey','Ez', 'Hx','Hy','Hz']] | None = None) -> tuple[np.ndarray, np.ndarray]:
828
826
  """Compute the farfield at the provided theta/phi coordinates
829
827
 
830
828
  Args:
@@ -874,7 +872,7 @@ class MWField:
874
872
 
875
873
  return Eff, Hff
876
874
 
877
- def optycal(self, faces: FaceSelection | GeoSurface = None) -> tuple:
875
+ def optycal(self, faces: FaceSelection | GeoSurface | None = None) -> tuple:
878
876
  """Export this models exterior to an Optical acceptable dataset
879
877
 
880
878
  Args:
@@ -953,7 +951,7 @@ class MWScalar:
953
951
  mode_number: int,
954
952
  k0: float,
955
953
  beta: float,
956
- Z0: float,
954
+ Z0: float | complex,
957
955
  Pout: float) -> None:
958
956
  i = self._portmap[port_number]
959
957
  self.beta[i] = beta
@@ -1026,9 +1024,9 @@ class MWScalarNdim:
1026
1024
 
1027
1025
  def export_touchstone(self,
1028
1026
  filename: str,
1029
- Z0ref: float = None,
1027
+ Z0ref: float | None = None,
1030
1028
  format: Literal['RI','MA','DB'] = 'RI',
1031
- custom_comments: list[str] = None,
1029
+ custom_comments: list[str] | None = None,
1032
1030
  funit: Literal['HZ','KHZ','MHZ','GHZ'] = 'GHZ'):
1033
1031
  """Export the S-parameter data to a touchstone file
1034
1032
 
@@ -1063,9 +1061,9 @@ class MWScalarNdim:
1063
1061
  filename: str,
1064
1062
  Smatrix: np.ndarray,
1065
1063
  frequencies: np.ndarray,
1066
- Z0ref: float = None,
1064
+ Z0ref: float | None = None,
1067
1065
  format: Literal['RI','MA','DB'] = 'RI',
1068
- custom_comments: list[str] = None,
1066
+ custom_comments: list[str] | None = None,
1069
1067
  funit: Literal['HZ','KHZ','MHZ','GHZ'] = 'GHZ') -> None:
1070
1068
  """Save an S-parameter matrix to a touchstone file.
1071
1069
 
@@ -19,19 +19,21 @@ from numba_progress import ProgressBar
19
19
  from ...mesh3d import SurfaceMesh
20
20
  import numpy as np
21
21
  from loguru import logger
22
- from numba import c8, c16, f8, i8, njit, prange, typeof, f4
23
- from numba.types import Tuple as TupleType
22
+ from numba import c16, njit, prange, f8
23
+ from numba.types import Tuple as TupleType # ty: ignore
24
24
  from numba_progress.progress import ProgressBarType
25
+ from ...const import Z0
25
26
 
26
27
  LR = 0.001
28
+
27
29
  @njit(
28
- TupleType((c8[:, :], c8[:, :]))(
29
- c8[:, :],
30
- c8[:, :],
31
- f4[:, :],
32
- f4[:, :],
33
- f4[:, :],
34
- f4,
30
+ TupleType((c16[:, :], c16[:, :]))(
31
+ c16[:, :],
32
+ c16[:, :],
33
+ f8[:, :],
34
+ f8[:, :],
35
+ f8[:, :],
36
+ f8,
35
37
  ProgressBarType,
36
38
  ),
37
39
  parallel=True,
@@ -86,17 +88,15 @@ def stratton_chu_ff(Ein, Hin, vis, wns, tpout, k0, pgb):
86
88
 
87
89
  N = tpout.shape[1]
88
90
 
89
- Eout = np.zeros((3, N)).astype(np.complex64)
90
- Hout = np.zeros((3, N)).astype(np.complex64)
91
-
92
- Eoutx = np.zeros((N,)).astype(np.complex64)
93
- Eouty = np.zeros((N,)).astype(np.complex64)
94
- Eoutz = np.zeros((N,)).astype(np.complex64)
91
+ Eout = np.zeros((3, N)).astype(np.complex128)
92
+ Hout = np.zeros((3, N)).astype(np.complex128)
95
93
 
96
- Z0 = np.float32(376.73031366857)
94
+ Eoutx = np.zeros((N,)).astype(np.complex128)
95
+ Eouty = np.zeros((N,)).astype(np.complex128)
96
+ Eoutz = np.zeros((N,)).astype(np.complex128)
97
97
 
98
- Q = np.complex64(-1j * k0 / (4 * np.pi))
99
- ii = np.complex64(1j)
98
+ Q = np.complex128(-1j * k0 / (4 * np.pi))
99
+ ii = np.complex128(1j)
100
100
 
101
101
  NxHx = ny * Hz - nz * Hy
102
102
  NxHy = nz * Hx - nx * Hz
@@ -106,7 +106,7 @@ def stratton_chu_ff(Ein, Hin, vis, wns, tpout, k0, pgb):
106
106
  NxEy = nz * Ex - nx * Ez
107
107
  NxEz = nx * Ey - ny * Ex
108
108
 
109
- for j in prange(Nids):
109
+ for j in prange(Nids): # ty: ignore
110
110
  xi = vx[j]
111
111
  yi = vy[j]
112
112
  zi = vz[j]
@@ -147,7 +147,7 @@ def stratton_chu(Ein, Hin, mesh: SurfaceMesh, theta: np.ndarray, phi: np.ndarray
147
147
  areas = mesh.areas
148
148
  vis = mesh.edge_centers
149
149
 
150
- wns = np.zeros_like(vis).astype(np.float32)
150
+ wns = np.zeros_like(vis).astype(np.float64)
151
151
 
152
152
  tri_normals = mesh.normals
153
153
  tri_ids = mesh.tri_to_edge
@@ -164,12 +164,12 @@ def stratton_chu(Ein, Hin, mesh: SurfaceMesh, theta: np.ndarray, phi: np.ndarray
164
164
  tpout = np.array([theta, phi])
165
165
  with ProgressBar(total=Ntot, ncols=100, dynamic_ncols=False) as pgb:
166
166
  Eout, Hout = stratton_chu_ff(
167
- Ein.astype(np.complex64),
168
- Hin.astype(np.complex64),
169
- vis.astype(np.float32),
170
- wns.astype(np.float32),
171
- tpout.astype(np.float32),
172
- np.float32(k0),
167
+ Ein.astype(np.complex128),
168
+ Hin.astype(np.complex128),
169
+ vis.astype(np.float64),
170
+ wns.astype(np.float64),
171
+ tpout.astype(np.float64),
172
+ np.float64(k0),
173
173
  pgb,
174
174
  )
175
175
  return Eout.astype(np.complex128), Hout.astype(np.complex128)
@@ -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
- B: csr_matrix = None
30
+ B: csr_matrix | None = 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 = None
52
+ self._active_port: int = -1
53
53
  self.reports: list[SolveReport] = []
54
54
  self.id: int = -1
55
55
  self.store_if_needed()
@@ -88,15 +88,20 @@ class SimJob:
88
88
 
89
89
  b_active = self.b + mode
90
90
  A = self.load_if_needed('A')
91
-
91
+
92
+ aux = {
93
+ 'Active port': str(key),
94
+ }
92
95
 
93
96
  if self.has_periodic:
94
97
  P = self.load_if_needed('P')
95
98
  Pd = self.load_if_needed('Pd')
96
99
  b_active = Pd @ b_active
97
100
  A = Pd @ A @ P
101
+ aux['Periodic reduction'] = str(P.shape)
98
102
 
99
- yield A, b_active, self.solve_ids, reuse_factorization
103
+
104
+ yield A, b_active, self.solve_ids, reuse_factorization, aux
100
105
 
101
106
  reuse_factorization = True
102
107
 
@@ -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 RobinBC
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: RobinBC,
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, ndpts=ndpts)
66
- norm = surface_integral(nodes, tri_vertices, inproduct2, ndpts=ndpts)
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: RobinBC,
73
+ bc: PortBC,
74
74
  k0: float,
75
75
  const: np.ndarray,
76
- ndpts: int = 4):
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
- ndpts: int = 4 the number of Duvanant integration points to use (default = 4)
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=ndpts)
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: RobinBC,
103
+ bc: PortBC,
104
104
  k0: float,
105
105
  fieldf: Callable,
106
106
  const: np.ndarray,
107
- ndpts: int = 4):
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
- ndpts: int = 4 the number of Duvanant integration points to use (default = 4)
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=ndpts)
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
@@ -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 | Iterable,*args, **kwargs):
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, k0: float, Npoints: int = 10, dv=(0,0,0), XYZ=None,
356
- field: Literal['E','H'] = 'E'):
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
- scalemode: Literal['lin','log'] = 'lin'):
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
- animate: bool = False,
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.