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
emerge/_emerge/solver.py
CHANGED
|
@@ -17,11 +17,11 @@
|
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
from __future__ import annotations
|
|
20
|
-
from scipy.sparse import lil_matrix, csc_matrix
|
|
21
|
-
from scipy.sparse.csgraph import reverse_cuthill_mckee
|
|
22
|
-
from scipy.sparse.linalg import bicgstab, gmres, gcrotmk, eigs, splu
|
|
23
|
-
from scipy.linalg import eig
|
|
24
|
-
from scipy import sparse
|
|
20
|
+
from scipy.sparse import lil_matrix, csc_matrix, csr_matrix # type: ignore
|
|
21
|
+
from scipy.sparse.csgraph import reverse_cuthill_mckee # type: ignore
|
|
22
|
+
from scipy.sparse.linalg import bicgstab, gmres, gcrotmk, eigs, splu # type: ignore
|
|
23
|
+
from scipy.linalg import eig # type: ignore
|
|
24
|
+
from scipy import sparse # type: ignore
|
|
25
25
|
from dataclasses import dataclass
|
|
26
26
|
import numpy as np
|
|
27
27
|
from loguru import logger
|
|
@@ -44,7 +44,7 @@ if 'arm' not in platform.processor():
|
|
|
44
44
|
except ModuleNotFoundError as e:
|
|
45
45
|
logger.info('Pardiso not found, defaulting to SuperLU')
|
|
46
46
|
try:
|
|
47
|
-
import scikits.umfpack as um
|
|
47
|
+
import scikits.umfpack as um # type: ignore
|
|
48
48
|
_UMFPACK_AVAILABLE = True
|
|
49
49
|
except ModuleNotFoundError as e:
|
|
50
50
|
logger.debug('UMFPACK not found, defaulting to SuperLU')
|
|
@@ -108,8 +108,8 @@ def filter_unique_eigenpairs(eigen_values: list[complex], eigen_vectors: list[np
|
|
|
108
108
|
unique_values (np.ndarray): Filtered eigenvalues
|
|
109
109
|
unique_vectors (np.ndarray): Corresponding orthogonal eigenvectors
|
|
110
110
|
"""
|
|
111
|
-
selected = []
|
|
112
|
-
indices = []
|
|
111
|
+
selected: list = []
|
|
112
|
+
indices: list = []
|
|
113
113
|
for i in range(len(eigen_vectors)):
|
|
114
114
|
|
|
115
115
|
vec = eigen_vectors[i]
|
|
@@ -166,7 +166,7 @@ class Sorter:
|
|
|
166
166
|
self.perm = None
|
|
167
167
|
self.inv_perm = None
|
|
168
168
|
|
|
169
|
-
def reset(self)
|
|
169
|
+
def reset(self):
|
|
170
170
|
""" Reset the permuation vectors."""
|
|
171
171
|
self.perm = None
|
|
172
172
|
self.inv_perm = None
|
|
@@ -234,7 +234,7 @@ class EigSolver:
|
|
|
234
234
|
def __str__(self) -> str:
|
|
235
235
|
return f'{self.__class__.__name__}'
|
|
236
236
|
|
|
237
|
-
def eig(self, A: lil_matrix, B:
|
|
237
|
+
def eig(self, A: lil_matrix | csr_matrix, B: lil_matrix | csr_matrix, nmodes: int = 6, target_k0: float = 0.0, which: str = 'LM', sign: float = 1.):
|
|
238
238
|
raise NotImplementedError("This classes eigenmdoe solver method is not implemented.")
|
|
239
239
|
|
|
240
240
|
def reset(self) -> None:
|
|
@@ -255,7 +255,7 @@ class SolveReport:
|
|
|
255
255
|
simtime: float
|
|
256
256
|
ndof: int
|
|
257
257
|
nnz: int
|
|
258
|
-
code: int =
|
|
258
|
+
code: int = 0
|
|
259
259
|
|
|
260
260
|
|
|
261
261
|
class ReverseCuthillMckee(Sorter):
|
|
@@ -339,7 +339,7 @@ class SolverGCROTMK(Solver):
|
|
|
339
339
|
convergence = np.linalg.norm((self.A @ xk - self.b))
|
|
340
340
|
logger.info(f'Iteration {convergence:.4f}')
|
|
341
341
|
|
|
342
|
-
def solve(self, A, b, precon, id: int = -1):
|
|
342
|
+
def solve(self, A: lil_matrix, b: np.ndarray, precon: Preconditioner, reuse_factorization: bool = False, id: int = -1):
|
|
343
343
|
logger.info(f'Calling GCRO-T(m,k) algorithm. ID={id}')
|
|
344
344
|
self.A = A
|
|
345
345
|
self.b = b
|
|
@@ -482,10 +482,10 @@ class SolverLAPACK(EigSolver):
|
|
|
482
482
|
super().__init__()
|
|
483
483
|
|
|
484
484
|
def eig(self,
|
|
485
|
-
A:
|
|
486
|
-
B:
|
|
485
|
+
A: lil_matrix | csr_matrix,
|
|
486
|
+
B: lil_matrix | csr_matrix,
|
|
487
487
|
nmodes: int = 6,
|
|
488
|
-
target_k0: float = 0,
|
|
488
|
+
target_k0: float | None = 0,
|
|
489
489
|
which: str = 'LM',
|
|
490
490
|
sign: float = 1.0):
|
|
491
491
|
"""
|
|
@@ -521,8 +521,8 @@ class SolverARPACK(EigSolver):
|
|
|
521
521
|
super().__init__()
|
|
522
522
|
|
|
523
523
|
def eig(self,
|
|
524
|
-
A:
|
|
525
|
-
B:
|
|
524
|
+
A: lil_matrix | csr_matrix,
|
|
525
|
+
B: lil_matrix | csr_matrix,
|
|
526
526
|
nmodes: int = 6,
|
|
527
527
|
target_k0: float = 0,
|
|
528
528
|
which: str = 'LM',
|
|
@@ -544,8 +544,8 @@ class SmartARPACK_BMA(EigSolver):
|
|
|
544
544
|
self.energy_limit: float = 1e-4
|
|
545
545
|
|
|
546
546
|
def eig(self,
|
|
547
|
-
A:
|
|
548
|
-
B:
|
|
547
|
+
A: lil_matrix | csr_matrix,
|
|
548
|
+
B: lil_matrix | csr_matrix,
|
|
549
549
|
nmodes: int = 6,
|
|
550
550
|
target_k0: float = 0,
|
|
551
551
|
which: str = 'LM',
|
|
@@ -593,8 +593,8 @@ class SmartARPACK(EigSolver):
|
|
|
593
593
|
self.energy_limit: float = 1e-4
|
|
594
594
|
|
|
595
595
|
def eig(self,
|
|
596
|
-
A:
|
|
597
|
-
B:
|
|
596
|
+
A: lil_matrix | csr_matrix,
|
|
597
|
+
B: lil_matrix | csr_matrix,
|
|
598
598
|
nmodes: int = 6,
|
|
599
599
|
target_k0: float = 0,
|
|
600
600
|
which: str = 'LM',
|
|
@@ -625,8 +625,8 @@ class SmartARPACK(EigSolver):
|
|
|
625
625
|
if len(tot_eigen_values)>nmodes:
|
|
626
626
|
break
|
|
627
627
|
#Sort solutions on mode energy
|
|
628
|
-
val, mode = filter_unique_eigenpairs(
|
|
629
|
-
val, mode = zip(*sorted(zip(val,mode), key=lambda x: x[0], reverse=False))
|
|
628
|
+
val, mode = filter_unique_eigenpairs(tot_eigen_values, tot_eigen_modes)
|
|
629
|
+
val, mode = zip(*sorted(zip(val,mode), key=lambda x: x[0], reverse=False)) # type: ignore
|
|
630
630
|
eigen_values = np.array(val[:nmodes])
|
|
631
631
|
eigen_modes = np.array(mode[:nmodes]).T
|
|
632
632
|
|
|
@@ -648,7 +648,7 @@ class EMSolver(Enum):
|
|
|
648
648
|
SMART_ARPACK = 6
|
|
649
649
|
SMART_ARPACK_BMA = 7
|
|
650
650
|
|
|
651
|
-
def get_solver(self) -> Solver:
|
|
651
|
+
def get_solver(self) -> Solver | EigSolver:
|
|
652
652
|
if self==EMSolver.SUPERLU:
|
|
653
653
|
return SolverSuperLU()
|
|
654
654
|
elif self==EMSolver.UMFPACK:
|
|
@@ -669,7 +669,7 @@ class EMSolver(Enum):
|
|
|
669
669
|
return SmartARPACK()
|
|
670
670
|
elif self==EMSolver.SMART_ARPACK_BMA:
|
|
671
671
|
return SmartARPACK_BMA()
|
|
672
|
-
|
|
672
|
+
|
|
673
673
|
|
|
674
674
|
############################################################
|
|
675
675
|
# SOLVE ROUTINE #
|
|
@@ -686,21 +686,21 @@ class SolveRoutine:
|
|
|
686
686
|
|
|
687
687
|
self.sorter: Sorter = ReverseCuthillMckee()
|
|
688
688
|
self.precon: Preconditioner = ILUPrecon()
|
|
689
|
-
self.solvers: dict[EMSolver, Solver] = {slv: slv.get_solver() for slv in EMSolver}
|
|
689
|
+
self.solvers: dict[EMSolver, Solver | EigSolver] = {slv: slv.get_solver() for slv in EMSolver}
|
|
690
690
|
|
|
691
691
|
self.parallel: Literal['SI','MT','MP'] = 'SI'
|
|
692
692
|
self.smart_search: bool = False
|
|
693
|
-
self.forced_solver: list[Solver] = []
|
|
694
|
-
self.disabled_solver: list[Solver] = []
|
|
693
|
+
self.forced_solver: list[Solver | EigSolver] = []
|
|
694
|
+
self.disabled_solver: list[type[Solver]|type[EigSolver]] = []
|
|
695
695
|
|
|
696
696
|
self.use_sorter: bool = False
|
|
697
697
|
self.use_preconditioner: bool = False
|
|
698
698
|
self.use_direct: bool = True
|
|
699
699
|
|
|
700
700
|
def __str__(self) -> str:
|
|
701
|
-
return
|
|
701
|
+
return 'SolveRoutine()'
|
|
702
702
|
|
|
703
|
-
def _legal_solver(self, solver: Solver) -> bool:
|
|
703
|
+
def _legal_solver(self, solver: Solver | EigSolver) -> bool:
|
|
704
704
|
"""Checks if a solver is a legal option.
|
|
705
705
|
|
|
706
706
|
Args:
|
|
@@ -718,7 +718,7 @@ class SolveRoutine:
|
|
|
718
718
|
return list([solver for solver in self.solvers.values() if not isinstance(solver, EigSolver)])
|
|
719
719
|
|
|
720
720
|
@property
|
|
721
|
-
def all_eig_solvers(self) -> list[
|
|
721
|
+
def all_eig_solvers(self) -> list[EigSolver]:
|
|
722
722
|
return list([solver for solver in self.solvers.values() if isinstance(solver, EigSolver)])
|
|
723
723
|
|
|
724
724
|
|
|
@@ -736,7 +736,7 @@ class SolveRoutine:
|
|
|
736
736
|
"""
|
|
737
737
|
solver = self.solvers[solver_type]
|
|
738
738
|
if self._legal_solver(solver):
|
|
739
|
-
return solver
|
|
739
|
+
return solver # type: ignore
|
|
740
740
|
for alternative in self.all_solvers:
|
|
741
741
|
if self._legal_solver(alternative):
|
|
742
742
|
logger.debug(f'Falling back on legal solver: {alternative}')
|
|
@@ -803,10 +803,10 @@ class SolveRoutine:
|
|
|
803
803
|
for solver in self.solvers.values():
|
|
804
804
|
solver.reset()
|
|
805
805
|
self.sorter.reset()
|
|
806
|
-
self.parallel
|
|
807
|
-
self.smart_search
|
|
806
|
+
self.parallel = 'SI'
|
|
807
|
+
self.smart_search = False
|
|
808
808
|
self.forced_solver = []
|
|
809
|
-
self.disabled_solver
|
|
809
|
+
self.disabled_solver = []
|
|
810
810
|
|
|
811
811
|
def _get_solver(self, A: lil_matrix, b: np.ndarray) -> Solver:
|
|
812
812
|
"""Returns the relevant Solver object given a certain matrix and source vector
|
|
@@ -844,7 +844,7 @@ class SolveRoutine:
|
|
|
844
844
|
"""
|
|
845
845
|
return self._try_solver(EMSolver.SUPERLU)
|
|
846
846
|
|
|
847
|
-
def _get_eig_solver(self, A: lil_matrix, b: lil_matrix, direct: bool = None) ->
|
|
847
|
+
def _get_eig_solver(self, A: lil_matrix, b: lil_matrix, direct: bool | None = None) -> EigSolver:
|
|
848
848
|
"""Returns the relevant eigenmode Solver object given a certain matrix and source vector
|
|
849
849
|
|
|
850
850
|
This is the default implementation for the SolveRoutine Class.
|
|
@@ -860,13 +860,13 @@ class SolveRoutine:
|
|
|
860
860
|
"""
|
|
861
861
|
for solver in self.forced_solver:
|
|
862
862
|
if isinstance(solver, EigSolver):
|
|
863
|
-
return solver
|
|
863
|
+
return solver # type: ignore
|
|
864
864
|
if direct or A.shape[0] < 1000:
|
|
865
|
-
return self.solvers[EMSolver.LAPACK]
|
|
865
|
+
return self.solvers[EMSolver.LAPACK] # type: ignore
|
|
866
866
|
else:
|
|
867
|
-
return self.solvers[EMSolver.SMART_ARPACK]
|
|
867
|
+
return self.solvers[EMSolver.SMART_ARPACK] # type: ignore
|
|
868
868
|
|
|
869
|
-
def _get_eig_solver_bma(self, A: lil_matrix, b: lil_matrix, direct: bool = None) ->
|
|
869
|
+
def _get_eig_solver_bma(self, A: lil_matrix, b: lil_matrix, direct: bool | None = None) -> EigSolver:
|
|
870
870
|
"""Returns the relevant eigenmode Solver object given a certain matrix and source vector
|
|
871
871
|
|
|
872
872
|
This is the default implementation for the SolveRoutine Class.
|
|
@@ -885,11 +885,11 @@ class SolveRoutine:
|
|
|
885
885
|
return solver
|
|
886
886
|
|
|
887
887
|
if direct or A.shape[0] < 1000:
|
|
888
|
-
return self.solvers[EMSolver.LAPACK]
|
|
888
|
+
return self.solvers[EMSolver.LAPACK] # type: ignore
|
|
889
889
|
else:
|
|
890
|
-
return self.solvers[EMSolver.ARPACK]
|
|
890
|
+
return self.solvers[EMSolver.ARPACK] # type: ignore
|
|
891
891
|
|
|
892
|
-
def solve(self, A:
|
|
892
|
+
def solve(self, A: lil_matrix | csc_matrix,
|
|
893
893
|
b: np.ndarray,
|
|
894
894
|
solve_ids: np.ndarray,
|
|
895
895
|
reuse: bool = False,
|
|
@@ -937,7 +937,7 @@ class SolveRoutine:
|
|
|
937
937
|
# Preconditioner
|
|
938
938
|
precon = 'None'
|
|
939
939
|
if self.use_preconditioner:
|
|
940
|
-
if not
|
|
940
|
+
if not solver.own_preconditioner:
|
|
941
941
|
self.precon.init(Asorted, bsorted)
|
|
942
942
|
precon = str(self.precon)
|
|
943
943
|
|
|
@@ -968,12 +968,12 @@ class SolveRoutine:
|
|
|
968
968
|
return solution, SolveReport(str(solver), sorter, precon, simtime, NS, A.nnz, code)
|
|
969
969
|
|
|
970
970
|
def eig_boundary(self,
|
|
971
|
-
A:
|
|
971
|
+
A: lil_matrix | csr_matrix,
|
|
972
972
|
B: np.ndarray,
|
|
973
973
|
solve_ids: np.ndarray,
|
|
974
974
|
nmodes: int = 6,
|
|
975
|
-
direct: bool = None,
|
|
976
|
-
target_k0: float =
|
|
975
|
+
direct: bool | None = None,
|
|
976
|
+
target_k0: float = 0.0,
|
|
977
977
|
which: str = 'LM',
|
|
978
978
|
sign: float=-1) -> tuple[np.ndarray, np.ndarray, SolveReport]:
|
|
979
979
|
""" Find the eigenmodes for the system Ax = λBx for a boundary mode problem
|
|
@@ -1010,15 +1010,15 @@ class SolveRoutine:
|
|
|
1010
1010
|
end = time.time()
|
|
1011
1011
|
|
|
1012
1012
|
simtime = end-start
|
|
1013
|
-
return eigen_values, eigen_modes, SolveReport(str(solver), 'None', 'None', simtime, NS, A.nnz, simtime)
|
|
1013
|
+
return eigen_values, eigen_modes, SolveReport(str(solver), 'None', 'None', simtime, NS, A.nnz, int(simtime))
|
|
1014
1014
|
|
|
1015
1015
|
def eig(self,
|
|
1016
|
-
A:
|
|
1016
|
+
A: lil_matrix | csr_matrix,
|
|
1017
1017
|
B: np.ndarray,
|
|
1018
1018
|
solve_ids: np.ndarray,
|
|
1019
1019
|
nmodes: int = 6,
|
|
1020
|
-
direct: bool = None,
|
|
1021
|
-
target_f0: float =
|
|
1020
|
+
direct: bool | None = None,
|
|
1021
|
+
target_f0: float = 0.0,
|
|
1022
1022
|
which: str = 'LM') -> tuple[np.ndarray, np.ndarray, SolveReport]:
|
|
1023
1023
|
"""
|
|
1024
1024
|
Find the eigenmodes for the system Ax = λBx for a boundary mode problem
|
|
@@ -1055,7 +1055,7 @@ class SolveRoutine:
|
|
|
1055
1055
|
for i in range(Nsols):
|
|
1056
1056
|
sols[solve_ids,i] = eigen_modes[:,i]
|
|
1057
1057
|
|
|
1058
|
-
return eigen_values, sols, SolveReport(str(solver), 'None', 'None', simtime, NS, A.nnz, simtime)
|
|
1058
|
+
return eigen_values, sols, SolveReport(str(solver), 'None', 'None', simtime, NS, A.nnz, int(simtime))
|
|
1059
1059
|
|
|
1060
1060
|
|
|
1061
1061
|
class AutomaticRoutine(SolveRoutine):
|