emerge 1.0.4__py3-none-any.whl → 1.0.6__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of emerge might be problematic. Click here for more details.

emerge/_emerge/solver.py CHANGED
@@ -90,11 +90,16 @@ class SolveReport:
90
90
  sorter: str = 'None'
91
91
  precon: str = 'None'
92
92
  aux: dict[str, str] = field(default_factory=dict)
93
+ worker_name: str = 'Unknown Worker'
93
94
 
94
95
  def add(self, **kwargs: str):
95
96
  for key, value in kwargs.items():
96
97
  self.aux[key] = str(value)
97
98
 
99
+ @property
100
+ def mdof(self) -> float:
101
+ return (self.ndof**2)/((self.simtime+1e-6)*1e6)
102
+
98
103
  def logprint(self, print_cal: Callable | None = None):
99
104
  if print_cal is None:
100
105
  print_cal = print
@@ -113,6 +118,7 @@ class SolveReport:
113
118
  parts.append(fmt("DOFsSolve", self.ndof_solve))
114
119
  parts.append(fmt("NNZSolve", self.nnz_solve))
115
120
  parts.append(fmt("Exit", self.exit_code))
121
+ parts.append(fmt("Worker",self.worker_name))
116
122
 
117
123
  if self.aux:
118
124
  for k, v in self.aux.items():
@@ -155,6 +161,7 @@ class SolveReport:
155
161
  row("DOFs (Solve)", self.ndof_solve)
156
162
  row("NNZ (Solve)", self.nnz_solve)
157
163
  row("Exit Code", self.exit_code)
164
+ row("Worker", self.worker_name)
158
165
  print_cal(border)
159
166
 
160
167
  if self.aux:
@@ -164,6 +171,8 @@ class SolveReport:
164
171
  row(str(k), v)
165
172
  print_cal(border)
166
173
 
174
+ def _pfx(name: str, id: int = 0) -> str:
175
+ return f'[{name}-j{id:03d}]'
167
176
  ############################################################
168
177
  # EIGENMODE FILTER ROUTINE #
169
178
  ############################################################
@@ -322,9 +331,10 @@ class Solver:
322
331
  req_sorter: bool = False
323
332
  released_gil: bool = False
324
333
 
325
- def __init__(self):
334
+ def __init__(self, pre: str = ''):
326
335
  self.own_preconditioner: bool = False
327
336
  self.initialized: bool = False
337
+ self.pre: str = pre
328
338
 
329
339
  def __str__(self) -> str:
330
340
  return f'{self.__class__.__name__}'
@@ -360,8 +370,9 @@ class EigSolver:
360
370
  real_only: bool = False
361
371
  req_sorter: bool = False
362
372
 
363
- def __init__(self):
373
+ def __init__(self, pre: str = ''):
364
374
  self.own_preconditioner: bool = False
375
+ self.pre: str = pre
365
376
 
366
377
  def initialize(self) -> None:
367
378
  return None
@@ -370,7 +381,7 @@ class EigSolver:
370
381
  return f'{self.__class__.__name__}'
371
382
 
372
383
  def duplicate(self) -> Solver:
373
- return self.__class__()
384
+ return self.__class__(self.pre)
374
385
 
375
386
  def eig(self, A: csr_matrix | csr_matrix, B: csr_matrix | csr_matrix, nmodes: int = 6,
376
387
  target_k0: float = 0.0, which: str = 'LM', sign: float = 1.):
@@ -444,10 +455,10 @@ class SolverBicgstab(Solver):
444
455
 
445
456
  def callback(self, xk):
446
457
  convergence = np.linalg.norm((self.A @ xk - self.b))
447
- logger.info(f'Iteration {convergence:.4f}')
458
+ logger.info(self.pre + f'Iteration {convergence:.4f}')
448
459
 
449
460
  def solve(self, A, b, precon, reuse_factorization: bool = False, id: int = -1) -> tuple[np.ndarray, SolveReport]:
450
- logger.info(f'[ID={id}] Calling BiCGStab.')
461
+ logger.info(f'{_pfx(self.pre,id)} Calling BiCGStab.')
451
462
  self.A = A
452
463
  self.b = b
453
464
  if precon.M is not None:
@@ -466,10 +477,10 @@ class SolverGCROTMK(Solver):
466
477
 
467
478
  def callback(self, xk):
468
479
  convergence = np.linalg.norm((self.A @ xk - self.b))
469
- logger.info(f'Iteration {convergence:.4f}')
480
+ logger.info(self.pre + f'Iteration {convergence:.4f}')
470
481
 
471
482
  def solve(self, A: csr_matrix, b: np.ndarray, precon: Preconditioner, reuse_factorization: bool = False, id: int = -1) -> tuple[np.ndarray, SolveReport]:
472
- logger.info(f'[ID={id}] Calling GCRO-T(m,k) algorithm')
483
+ logger.info(f'{_pfx(self.pre,id)} Calling GCRO-T(m,k) algorithm')
473
484
  self.A = A
474
485
  self.b = b
475
486
  if precon.M is not None:
@@ -492,10 +503,10 @@ class SolverGMRES(Solver):
492
503
 
493
504
  def callback(self, norm):
494
505
  #convergence = np.linalg.norm((self.A @ xk - self.b))
495
- logger.info(f'Iteration {norm:.4f}')
506
+ logger.info(self.pre + f'Iteration {norm:.4f}')
496
507
 
497
508
  def solve(self, A, b, precon, reuse_factorization: bool = False, id: int = -1) -> tuple[np.ndarray, SolveReport]:
498
- logger.info(f'[ID={id}] Calling GMRES Function.')
509
+ logger.info(f'{_pfx(self.pre,id)} Calling GMRES Function.')
499
510
  self.A = A
500
511
  self.b = b
501
512
  if precon.M is not None:
@@ -516,8 +527,8 @@ class SolverSuperLU(Solver):
516
527
  real_only: bool = False
517
528
  released_gil: bool = True
518
529
 
519
- def __init__(self):
520
- super().__init__()
530
+ def __init__(self, pre: str):
531
+ super().__init__(pre)
521
532
  self.atol = 1e-5
522
533
 
523
534
  self.A: np.ndarray = None
@@ -527,7 +538,7 @@ class SolverSuperLU(Solver):
527
538
  self.lu = None
528
539
 
529
540
  def duplicate(self) -> Solver:
530
- new_solver = self.__class__()
541
+ new_solver = self.__class__(self.pre)
531
542
  new_solver._pivoting_threshold = self._pivoting_threshold
532
543
  return new_solver
533
544
 
@@ -537,11 +548,11 @@ class SolverSuperLU(Solver):
537
548
  self._pivoting_threshold = pivoting_threshold
538
549
 
539
550
  def solve(self, A, b, precon, reuse_factorization: bool = False, id: int = -1) -> tuple[np.ndarray, SolveReport]:
540
- logger.info(f'[ID={id}] Calling SuperLU Solver.')
551
+ logger.info(f'{_pfx(self.pre,id)} Calling SuperLU Solver.')
541
552
 
542
553
  self.single = True
543
554
  if not reuse_factorization:
544
- logger.trace('Computing LU-Decomposition')
555
+ logger.trace(self.pre + 'Computing LU-Decomposition')
545
556
  self.lu = splu(A, permc_spec='MMD_AT_PLUS_A', relax=0, diag_pivot_thresh=self._pivoting_threshold, options=self.options)
546
557
  x = self.lu.solve(b)
547
558
  aux = {
@@ -554,9 +565,9 @@ class SolverUMFPACK(Solver):
554
565
  req_sorter = False
555
566
  real_only = False
556
567
 
557
- def __init__(self):
558
- super().__init__()
559
- logger.trace('Creating UMFPACK solver')
568
+ def __init__(self, pre: str):
569
+ super().__init__(pre)
570
+ logger.trace(self.pre + 'Creating UMFPACK solver')
560
571
  self.A: np.ndarray = None
561
572
  self.b: np.ndarray = None
562
573
 
@@ -571,7 +582,7 @@ class SolverUMFPACK(Solver):
571
582
  def initialize(self):
572
583
  if self.initalized:
573
584
  return
574
- logger.trace('Initializing UMFPACK Solver')
585
+ logger.trace(self.pre + 'Initializing UMFPACK Solver')
575
586
  self.umfpack = um.UmfpackContext('zl')
576
587
  self.umfpack.control[um.UMFPACK_PRL] = 0 # ty: ignore
577
588
  self.umfpack.control[um.UMFPACK_IRSTEP] = 2 # ty: ignore
@@ -584,7 +595,7 @@ class SolverUMFPACK(Solver):
584
595
  self.initalized = True
585
596
 
586
597
  def reset(self) -> None:
587
- logger.trace('Resetting UMFPACK solver state')
598
+ logger.trace(self.pre + 'Resetting UMFPACK solver state')
588
599
  self.fact_symb = False
589
600
 
590
601
  def set_options(self, pivoting_threshold: float | None = None) -> None:
@@ -595,23 +606,23 @@ class SolverUMFPACK(Solver):
595
606
  self._pivoting_threshold = pivoting_threshold
596
607
 
597
608
  def duplicate(self) -> Solver:
598
- new_solver = self.__class__()
609
+ new_solver = self.__class__(self.pre)
599
610
  new_solver.set_options(pivoting_threshold = self._pivoting_threshold)
600
611
  return new_solver
601
612
 
602
613
  def solve(self, A, b, precon, reuse_factorization: bool = False, id: int = -1) -> tuple[np.ndarray, SolveReport]:
603
- logger.info(f'[ID={id}] Calling UMFPACK Solver.')
614
+ logger.info(f'{_pfx(self.pre,id)} Calling UMFPACK Solver.')
604
615
  A.indptr = A.indptr.astype(np.int64)
605
616
  A.indices = A.indices.astype(np.int64)
606
617
  if self.fact_symb is False:
607
- logger.trace(f'[ID={id}] Executing symbollic factorization.')
618
+ logger.trace(f'{_pfx(self.pre,id)} Executing symbollic factorization.')
608
619
  self.umfpack.symbolic(A)
609
620
  self.fact_symb = True
610
621
  if not reuse_factorization:
611
- logger.trace(f'[ID={id}] Executing numeric factorization.')
622
+ logger.trace(f'{_pfx(self.pre,id)} Executing numeric factorization.')
612
623
  self.umfpack.numeric(A)
613
624
  self.A = A
614
- logger.trace(f'[ID={id}] Solving linear system.')
625
+ logger.trace(f'{_pfx(self.pre,id)} Solving linear system.')
615
626
  x = self.umfpack.solve(um.UMFPACK_A, self.A, b, autoTranspose = False ) # ty: ignore
616
627
  aux = {
617
628
  "Pivoting Threshold": str(self._pivoting_threshold),
@@ -623,8 +634,8 @@ class SolverPardiso(Solver):
623
634
  real_only: bool = False
624
635
  req_sorter: bool = False
625
636
 
626
- def __init__(self):
627
- super().__init__()
637
+ def __init__(self, pre: str):
638
+ super().__init__(pre)
628
639
  self.solver: PardisoInterface | None = None
629
640
  self.fact_symb: bool = False
630
641
  self.A: np.ndarray = None
@@ -637,29 +648,30 @@ class SolverPardiso(Solver):
637
648
  self.initialized = True
638
649
 
639
650
  def solve(self, A, b, precon, reuse_factorization: bool = False, id: int = -1) -> tuple[np.ndarray, SolveReport]:
640
- logger.info(f'[ID={id}] Calling Pardiso Solver')
651
+ logger.info(f'{_pfx(self.pre,id)} Calling Pardiso Solver')
641
652
  if self.fact_symb is False:
642
- logger.trace(f'[ID={id}] Executing symbollic factorization.')
653
+ logger.trace(f'{_pfx(self.pre,id)} Executing symbollic factorization.')
643
654
  self.solver.symbolic(A)
644
655
  self.fact_symb = True
645
656
  if not reuse_factorization:
646
- logger.trace(f'[ID={id}] Executing numeric factorization.')
657
+ logger.trace(f'{_pfx(self.pre,id)} Executing numeric factorization.')
647
658
  self.solver.numeric(A)
648
659
  self.A = A
649
- logger.trace(f'[ID={id}] Solving linear system.')
660
+ logger.trace(f'{_pfx(self.pre,id)} Solving linear system.')
650
661
  x, error = self.solver.solve(A, b)
651
662
  if error != 0:
652
- logger.error(f'[ID={id}] Terminated with error code {error}')
653
- logger.error(self.solver.get_error(error))
654
- raise SimulationError(f'[ID={id}] PARDISO Terminated with error code {error}')
663
+ logger.error(f'{_pfx(self.pre,id)} Terminated with error code {error}')
664
+ logger.error(self.pre + self.solver.get_error(error))
665
+ raise SimulationError(f'{_pfx(self.pre,id)} PARDISO Terminated with error code {error}')
655
666
  aux = {}
656
667
  return x, SolveReport(solver=str(self), exit_code=error, aux=aux)
657
668
 
658
669
 
659
670
  class SolverCuDSS(Solver):
660
671
  real_only = False
661
- def __init__(self):
662
- super().__init__()
672
+
673
+ def __init__(self, pre: str):
674
+ super().__init__(pre)
663
675
  self._cudss: CuDSSInterface | None = None
664
676
  self.fact_symb: bool = False
665
677
  self.fact_numb: bool = False
@@ -676,18 +688,18 @@ class SolverCuDSS(Solver):
676
688
  self.fact_numb = False
677
689
 
678
690
  def solve(self, A, b, precon, reuse_factorization: bool = False, id: int = -1):
679
- logger.info(f'[ID={id}] Calling cuDSS Solver')
691
+ logger.info(f'{_pfx(self.pre,id)} Calling cuDSS Solver')
680
692
 
681
693
  if self.fact_symb is False:
682
- logger.trace(f'[ID={id}] Starting from symbollic factorization.')
694
+ logger.trace(f'{_pfx(self.pre,id)} Starting from symbollic factorization.')
683
695
  x = self._cudss.from_symbolic(A,b)
684
696
  self.fact_symb = True
685
697
  else:
686
698
  if reuse_factorization:
687
- logger.trace(f'[ID={id}] Solving linear system.')
699
+ logger.trace(f'{_pfx(self.pre,id)} Solving linear system.')
688
700
  x = self._cudss.from_solve(b)
689
701
  else:
690
- logger.trace(f'[ID={id}] Starting from numeric factorization.')
702
+ logger.trace(f'{_pfx(self.pre,id)} Starting from numeric factorization.')
691
703
  x = self._cudss.from_numeric(A,b)
692
704
 
693
705
  return x, SolveReport(solver=str(self), exit_code=0, aux={})
@@ -699,8 +711,6 @@ class SolverCuDSS(Solver):
699
711
 
700
712
  class SolverLAPACK(EigSolver):
701
713
 
702
- def __init__(self):
703
- super().__init__()
704
714
 
705
715
  def eig(self,
706
716
  A: csr_matrix | csr_matrix,
@@ -725,7 +735,7 @@ class SolverLAPACK(EigSolver):
725
735
  lam : (m,) real ndarray eigenvalues (m = n or k)
726
736
  vecs : (n, m) complex ndarray eigenvectors, B-orthonormal (xiᴴ B xj = δij)
727
737
  """
728
- logger.debug('Calling LAPACK eig solver')
738
+ logger.info(f'{_pfx(self.pre)} Calling LAPACK eig solver')
729
739
  lam, vecs = eig(A.toarray(), B.toarray(), overwrite_a=True, overwrite_b=True, check_finite=False)
730
740
  lam, vecs = filter_real_modes(lam, vecs, target_k0, 2, 2, sign=sign)
731
741
  return lam, vecs
@@ -738,8 +748,6 @@ class SolverLAPACK(EigSolver):
738
748
 
739
749
  class SolverARPACK(EigSolver):
740
750
  """ Implements the Scipy ARPACK iterative eigenmode solver."""
741
- def __init__(self):
742
- super().__init__()
743
751
 
744
752
  def eig(self,
745
753
  A: csr_matrix | csr_matrix,
@@ -748,7 +756,7 @@ class SolverARPACK(EigSolver):
748
756
  target_k0: float = 0,
749
757
  which: str = 'LM',
750
758
  sign: float = 1.0) -> tuple[np.ndarray, np.ndarray]:
751
- logger.info(f'Searching around β = {target_k0:.2f} rad/m with ARPACK')
759
+ logger.info(f'{_pfx(self.pre)} Searching around β = {target_k0:.2f} rad/m with ARPACK')
752
760
  sigma = sign*(target_k0**2)
753
761
  eigen_values, eigen_modes = eigs(A, k=nmodes, M=B, sigma=sigma, which=which)
754
762
  return eigen_values, eigen_modes
@@ -758,8 +766,8 @@ class SmartARPACK_BMA(EigSolver):
758
766
 
759
767
  The Solver searches in a geometric range around the target wave constant.
760
768
  """
761
- def __init__(self):
762
- super().__init__()
769
+ def __init__(self, pre: str):
770
+ super().__init__(pre)
763
771
  self.symmetric_steps: int = 41
764
772
  self.search_range: float = 2.0
765
773
  self.energy_limit: float = 1e-4
@@ -772,7 +780,7 @@ class SmartARPACK_BMA(EigSolver):
772
780
  which: str = 'LM',
773
781
  sign: float = 1.) -> tuple[np.ndarray, np.ndarray]:
774
782
 
775
- logger.info(f'Searching around β = {target_k0:.2f} rad/m with SmartARPACK (BMA)')
783
+ logger.info(f'{_pfx(self.pre)} Searching around β = {target_k0:.2f} rad/m with SmartARPACK (BMA)')
776
784
  qs = np.geomspace(1, self.search_range, self.symmetric_steps)
777
785
  tot_eigen_values = []
778
786
  tot_eigen_modes = []
@@ -808,8 +816,8 @@ class SmartARPACK(EigSolver):
808
816
 
809
817
  The Solver searches in a geometric range around the target wave constant.
810
818
  """
811
- def __init__(self):
812
- super().__init__()
819
+ def __init__(self, pre: str):
820
+ super().__init__(pre)
813
821
  self.symmetric_steps: int = 3
814
822
  self.search_range: float = 2.0
815
823
  self.energy_limit: float = 1e-4
@@ -821,7 +829,7 @@ class SmartARPACK(EigSolver):
821
829
  target_k0: float = 0,
822
830
  which: str = 'LM',
823
831
  sign: float = 1.) -> tuple[np.ndarray, np.ndarray]:
824
- logger.info(f'Searching around β = {target_k0:.2f} rad/m with SmartARPACK')
832
+ logger.info(f'{_pfx(self.pre)} Searching around β = {target_k0:.2f} rad/m with SmartARPACK')
825
833
  qs = np.geomspace(1, self.search_range, self.symmetric_steps)
826
834
  tot_eigen_values = []
827
835
  tot_eigen_modes = []
@@ -871,14 +879,14 @@ class EMSolver(Enum):
871
879
  SMART_ARPACK_BMA = 7
872
880
  CUDSS = 8
873
881
 
874
- def create_solver(self) -> Solver | EigSolver | None:
882
+ def create_solver(self, pre: str) -> Solver | EigSolver | None:
875
883
  if self==EMSolver.UMFPACK and not _UMFPACK_AVAILABLE:
876
884
  return None
877
885
  elif self==EMSolver.PARDISO and not _PARDISO_AVAILABLE:
878
886
  return None
879
887
  if self==EMSolver.CUDSS and not _CUDSS_AVAILABLE:
880
888
  return None
881
- return self._clss()
889
+ return self._clss(pre)
882
890
 
883
891
  @property
884
892
  def _clss(self) -> type[Solver]:
@@ -907,11 +915,15 @@ class SolveRoutine:
907
915
  and goes through a sequence of steps to solve a linear system or find eigenmodes.
908
916
 
909
917
  """
910
- def __init__(self):
918
+ def __init__(self, thread_nr: int = 0, proc_nr: int = 0):
919
+
920
+ self.pre: str = ''
921
+ self._set_name(thread_nr, proc_nr)
922
+
911
923
 
912
924
  self.sorter: Sorter = ReverseCuthillMckee()
913
925
  self.precon: Preconditioner = ILUPrecon()
914
- self.solvers: dict[EMSolver, Solver | EigSolver] = {slv: slv.create_solver() for slv in EMSolver}
926
+ self.solvers: dict[EMSolver, Solver | EigSolver] = {slv: slv.create_solver(self.pre) for slv in EMSolver}
915
927
  self.solvers = {key: solver for key, solver in self.solvers.items() if solver is not None}
916
928
 
917
929
  self.parallel: Literal['SI','MT','MP'] = 'SI'
@@ -922,8 +934,11 @@ class SolveRoutine:
922
934
  self.use_sorter: bool = False
923
935
  self.use_preconditioner: bool = False
924
936
  self.use_direct: bool = True
937
+
925
938
 
926
-
939
+ def _set_name(self, thread_nr: int, proc_nr: int):
940
+ self.pre = f'p{int(proc_nr):02d}/t{int(thread_nr):02d}'
941
+
927
942
  def __str__(self) -> str:
928
943
  return 'SolveRoutine()'
929
944
 
@@ -936,11 +951,11 @@ class SolveRoutine:
936
951
  Returns:
937
952
  bool: If the solver is legal
938
953
  """
939
- if any(isinstance(solver, solvertype) for solvertype in self.disabled_solver):
940
- logger.warning(f'The selected solver {solver} cannot be used as it is disabled.')
954
+ if any(isinstance(solver, solvertype.__class__) for solvertype in self.disabled_solver):
955
+ logger.warning(self.pre + f'The selected solver {solver} cannot be used as it is disabled.')
941
956
  return False
942
957
  if self.parallel=='MT' and not solver.released_gil:
943
- logger.warning(f'The selected solver {solver} cannot be used in MultiThreading as it does not release the GIL')
958
+ logger.warning(self.pre + f'The selected solver {solver} cannot be used in MultiThreading as it does not release the GIL')
944
959
  return False
945
960
  return True
946
961
 
@@ -969,9 +984,9 @@ class SolveRoutine:
969
984
  return solver # type: ignore
970
985
  for alternative in self.all_solvers:
971
986
  if self._legal_solver(alternative):
972
- logger.debug(f'Falling back on legal solver: {alternative}')
987
+ logger.debug(self.pre + f'Falling back on legal solver: {alternative}')
973
988
  return alternative
974
- raise RuntimeError(f'No legal solver could be found. The following are disabled: {self.disabled_solver}')
989
+ raise RuntimeError(self.pre + f'No legal solver could be found. The following are disabled: {self.disabled_solver}')
975
990
 
976
991
  def duplicate(self) -> SolveRoutine:
977
992
  """Creates a copy of this SolveRoutine class object.
@@ -1009,13 +1024,15 @@ class SolveRoutine:
1009
1024
  """
1010
1025
  for solver in solvers:
1011
1026
  if isinstance(solver, EMSolver):
1012
- self.disabled_solver.append(solver.create_solver().__class__)
1027
+ self.disabled_solver.append(self.solvers[solver])
1013
1028
  else:
1014
- self.disabled_solver.append(solver.__class__)
1029
+ self.disabled_solver.append(solver)
1015
1030
 
1016
1031
  def _configure_routine(self,
1017
1032
  parallel: Literal['SI','MT','MP'] = 'SI',
1018
- smart_search: bool = False) -> SolveRoutine:
1033
+ smart_search: bool = False,
1034
+ thread_nr: int = 0,
1035
+ proc_nr: int = 0) -> SolveRoutine:
1019
1036
  """Configure the solver with the given settings
1020
1037
 
1021
1038
  Args:
@@ -1032,6 +1049,12 @@ class SolveRoutine:
1032
1049
  """
1033
1050
  self.parallel = parallel
1034
1051
  self.smart_search = smart_search
1052
+ if thread_nr != 1 or proc_nr != 1:
1053
+ self._set_name(thread_nr, proc_nr)
1054
+ for solver in self.solvers.values():
1055
+ if not isinstance(solver, (Solver, EigSolver)):
1056
+ continue
1057
+ solver.pre = self.pre
1035
1058
  return self
1036
1059
 
1037
1060
  def configure(self,
@@ -1171,10 +1194,10 @@ class SolveRoutine:
1171
1194
  bsel = b[solve_ids]
1172
1195
  nnz = Asel.nnz
1173
1196
 
1174
- logger.debug(f'[ID={id}] Removed {NF-NS} prescribed DOFs ({NS:,} left, {nnz:,}≠0)')
1197
+ logger.debug(f'{_pfx(self.pre,id)} Removed {NF-NS} prescribed DOFs ({NS:,} left, {nnz:,}≠0)')
1175
1198
 
1176
1199
  if solver.real_only:
1177
- logger.debug(f'[ID={id}] Converting to real matrix')
1200
+ logger.debug(f'{_pfx(self.pre,id)} Converting to real matrix')
1178
1201
  Asel, bsel = complex_to_real_block(Asel, bsel)
1179
1202
 
1180
1203
  # SORT
@@ -1197,8 +1220,8 @@ class SolveRoutine:
1197
1220
  x_solved, report = solver.solve(Asorted, bsorted, self.precon, reuse_factorization=reuse, id=id)
1198
1221
  end = time.time()
1199
1222
  simtime = end-start
1200
- logger.info(f'[ID={id}] Elapsed time taken: {simtime:.3f} seconds')
1201
- logger.debug(f'[ID={id}] O(N²) performance = {(NS**2)/((end-start+1e-6)*1e6):.3f} MDoF/s')
1223
+ logger.info(f'{_pfx(self.pre,id)} Elapsed time taken: {simtime:.3f} seconds')
1224
+ logger.debug(f'{_pfx(self.pre,id)} O(N²) performance = {(NS**2)/((end-start+1e-6)*1e6):.3f} MDoF/s')
1202
1225
 
1203
1226
  if self.use_sorter and solver.req_sorter:
1204
1227
  x = self.sorter.unsort(x_solved)
@@ -1206,14 +1229,14 @@ class SolveRoutine:
1206
1229
  x = x_solved
1207
1230
 
1208
1231
  if solver.real_only:
1209
- logger.debug(f'[ID={id}] Converting back to complex matrix')
1232
+ logger.debug(f'{_pfx(self.pre,id)} Converting back to complex matrix')
1210
1233
  x = real_to_complex_block(x)
1211
1234
 
1212
1235
  solution = np.zeros((NF,), dtype=np.complex128)
1213
1236
 
1214
1237
  solution[solve_ids] = x
1215
1238
 
1216
- logger.debug(f'[ID={id}] Solver complete!')
1239
+ logger.debug(f'{_pfx(self.pre,id)} Solver complete!')
1217
1240
  report.jobid = id
1218
1241
  report.sorter = str(sorter)
1219
1242
  report.simtime = simtime
@@ -1222,6 +1245,7 @@ class SolveRoutine:
1222
1245
  report.nnz_solve = Asorted.nnz
1223
1246
  report.ndof_solve = bsorted.shape[0]
1224
1247
  report.precon = precon
1248
+ report.worker_name = self.pre
1225
1249
 
1226
1250
  return solution, report
1227
1251
 
@@ -1258,7 +1282,7 @@ class SolveRoutine:
1258
1282
  NF = A.shape[0]
1259
1283
  NS = solve_ids.shape[0]
1260
1284
 
1261
- logger.debug(f'Removing {NF-NS} prescribed DOFs ({NS} left)')
1285
+ logger.debug(self.pre + f'Removing {NF-NS} prescribed DOFs ({NS} left)')
1262
1286
 
1263
1287
  Asel = A[np.ix_(solve_ids, solve_ids)]
1264
1288
  Bsel = B[np.ix_(solve_ids, solve_ids)]
@@ -1301,7 +1325,7 @@ class SolveRoutine:
1301
1325
  NF = A.shape[0]
1302
1326
  NS = solve_ids.shape[0]
1303
1327
 
1304
- logger.debug(f'Removing {NF-NS} prescribed DOFs ({NS} left)')
1328
+ logger.debug(self.pre + f'Removing {NF-NS} prescribed DOFs ({NS} left)')
1305
1329
 
1306
1330
  Asel = A[np.ix_(solve_ids, solve_ids)]
1307
1331
  Bsel = B[np.ix_(solve_ids, solve_ids)]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: emerge
3
- Version: 1.0.4
3
+ Version: 1.0.6
4
4
  Summary: An open source EM FEM simulator in Python
5
5
  Project-URL: Homepage, https://github.com/FennisRobert/EMerge
6
6
  Project-URL: Issues, https://github.com/FennisRobert/EMerge/issues
@@ -32,7 +32,7 @@ Hello everybody. Thanks for showing interest in this repository.
32
32
  Feel free to download your version of EMerge and start playing around with it!
33
33
  If you have suggestions/changes/questions either use the Github issue system or join the Discord using the following link:
34
34
 
35
- **https://discord.gg/uArxywnz**
35
+ **[Discord Invitation](https://discord.gg/VMftDCZcNz)**
36
36
 
37
37
  ## How to install
38
38
 
@@ -1,4 +1,4 @@
1
- emerge/__init__.py,sha256=hgaavnd2z2brL5QWk8XSNpqE3GDT54YHyQ9eeLgcCdA,3122
1
+ emerge/__init__.py,sha256=m1aBdjv_Ae2k7RzIgtl-5CMEH5FQmWw28SOk0V_ro0Y,3162
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
@@ -14,19 +14,19 @@ emerge/_emerge/cs.py,sha256=gULfov6s0jODOdQkH6NmGBbG5wvny1-bJU8fdAlpCHo,19730
14
14
  emerge/_emerge/dataset.py,sha256=UcSAJ_siLrOjNBBWRWsS3GUZUpayp63EM6pP6ClwKDI,1534
15
15
  emerge/_emerge/emerge_update.py,sha256=0G91xr7k7Me5gOlk3pXbKWe-6ALXtoCJ5syTa1Y5Bhw,2042
16
16
  emerge/_emerge/geo2d.py,sha256=e_HkX1GQ2iYrdO0zeEgzVOzfGyU1WGJyjeGBAobOttE,3323
17
- emerge/_emerge/geometry.py,sha256=-QLLDyYXCXfZW01aKwW8IfkvtAr5PVjsM4r-xtEbOzY,24677
17
+ emerge/_emerge/geometry.py,sha256=9WnZt2xtF4HEJfdPyT41i_q8gRMZRrG0C9PILaz1PvA,25523
18
18
  emerge/_emerge/howto.py,sha256=c4UxUNpA1tygr3OoR-LH-h0UZv-Tf9K8tpCiAU18BKE,8173
19
19
  emerge/_emerge/logsettings.py,sha256=OpsH_1dQAdZry_as8y0OQt4yKP_AMFfQG2d5Nz5yywg,4789
20
- emerge/_emerge/material.py,sha256=q6dhtfxPfy1PbCRjG7-jOimR5dVE6vf1kyfpBdoYrK4,16038
20
+ emerge/_emerge/material.py,sha256=zXmKEZctqz4T574KSfRMdhiT2F_6l-QwiqlxNx6zkI0,17451
21
21
  emerge/_emerge/mesh3d.py,sha256=6NWTqJVwyaOhFKQgNghkH3zgrYFWbI0qAEBpvq-JOwI,35790
22
- emerge/_emerge/mesher.py,sha256=64hMTe2sSQgytnf8ryXUH8PIkUOsV5KJEXpibgJOhSg,16052
22
+ emerge/_emerge/mesher.py,sha256=AUrMhXHHf1O5QtEyKlB172kV0B17jq9nzjq4JADZTV4,16079
23
23
  emerge/_emerge/periodic.py,sha256=dUuWqjlDR8mHtQR3ecINP2FFjJJ0cKg0blOVZ0PCcAo,12087
24
24
  emerge/_emerge/plot.py,sha256=cf1I9mj7EIUJcq8vmANlUkqoV6QqVaJaP-zlC-T9E18,8041
25
25
  emerge/_emerge/selection.py,sha256=ltT8ubMFG3-sFrAh7K7iAgSoBt3r25B02ShzMlOGSXQ,21527
26
26
  emerge/_emerge/settings.py,sha256=wZFMzQSnMEEJptatu--67El1L0I_YEv9S8QjqI69bfs,265
27
- emerge/_emerge/simmodel.py,sha256=8p82_R_hFAd1gOaLn6kaeFyQGJAQKjE04iZethx3V_o,26458
27
+ emerge/_emerge/simmodel.py,sha256=yw21pUhO2_BB3vTN4UY7fhZxXuWNvcTaA5xRCcUg7vs,26525
28
28
  emerge/_emerge/simulation_data.py,sha256=23o-xbm6Q6s9sYisyK9u1GTmuaXRl0WDGQwzPO7lkr0,15115
29
- emerge/_emerge/solver.py,sha256=Li8CYXuK-B-iXZ2z9SD-g8xJs0t86CtJsT3_7BxqKgE,51469
29
+ emerge/_emerge/solver.py,sha256=imgvQkVE9B3QEA1WmsBhhOLzHO44-Oh-onMXmLnfCFY,52980
30
30
  emerge/_emerge/system.py,sha256=p4HNz7d_LMRNE9Gk75vVdFecDH2iN_groAM9u-yQTpk,1618
31
31
  emerge/_emerge/elements/__init__.py,sha256=I3n9aic6lJW-oGeqTEZ-Fpxvyl2i-WqsHdnrM3v1oB8,799
32
32
  emerge/_emerge/elements/femdata.py,sha256=ZSB7dICyU3GOWbxpuowBc-Khh2mpXa02ZfMkHwdDol4,8377
@@ -35,13 +35,13 @@ emerge/_emerge/elements/ned2_interp.py,sha256=BGRdJGXCcDdqMBf3pOvc_-m-vngRI1VvE5
35
35
  emerge/_emerge/elements/nedelec2.py,sha256=OssFCnPp7wkMBcUISGvTgT94jayfGOmX0x-RctIYSuI,6645
36
36
  emerge/_emerge/elements/nedleg2.py,sha256=1SA6AvnbChhU2iodS1PVMUdbSn9wF2XKam12WTBDtsw,9049
37
37
  emerge/_emerge/geo/__init__.py,sha256=yTeuT4Oexrsdkr7MxRLeTHEY5iP4IHsWeCvit57fK5g,1161
38
- emerge/_emerge/geo/horn.py,sha256=otrtPphO2zoRaSOb7NV-iRaydL1uWDAl2xJ6-8Sef24,4148
38
+ emerge/_emerge/geo/horn.py,sha256=tI-w-O0Fm_siMaVhKpZ_k5URLfZkqcbEpURX94fhKDs,4645
39
39
  emerge/_emerge/geo/modeler.py,sha256=_PMz3lFSa7FmJHWdY-4U1Sqbed-Egy85S_AdjlCldC4,15572
40
- emerge/_emerge/geo/operations.py,sha256=cKQfVjN0Qt9tj91w7zevm7EKsYPxcD8TRFCeQMQZFwY,12446
41
- emerge/_emerge/geo/pcb.py,sha256=Mzn7Lho18Xc7A-XShfWZK9Kop4xlLYONMeRhtKkETJU,57577
40
+ emerge/_emerge/geo/operations.py,sha256=WYWfOXWrT0voeKW9U26g-PhQfqJl3ovRQ8uDQXUr7Nc,12459
41
+ emerge/_emerge/geo/pcb.py,sha256=oRx9CnFFzhnDNtwxnw2rcm_CtN1h2y3-0jXOaBqGZ_E,57544
42
42
  emerge/_emerge/geo/pmlbox.py,sha256=gaIG_AoZNQnIyJ8C7x64U-Hw5dsmllWMiZDAH4iRoM0,8784
43
- emerge/_emerge/geo/polybased.py,sha256=G4oJG7I7oZ69PKiQVoAOPSNAWnjhuYUDdqibZhUdiv4,32059
44
- emerge/_emerge/geo/shapes.py,sha256=LPprT9vR7p6TqSBVKS6eG8P3iYWO7_yC7LNUYw5B8Sk,24196
43
+ emerge/_emerge/geo/polybased.py,sha256=D_Ef4anrwV2RArEFrvWppZ_c7oN_Hm5h7ltMi2U3v2o,32891
44
+ emerge/_emerge/geo/shapes.py,sha256=bLZM8ey05yvpKGgZS_DXFDaTQRP5kpsc7Xgp6Xaxc_Q,26903
45
45
  emerge/_emerge/geo/step.py,sha256=XcAiEN8W4umNmZdYmrGHX_aJUuiMgc6vgT-UIk8Gbqc,2689
46
46
  emerge/_emerge/geo/pcb_tools/calculator.py,sha256=VbMP2xC9i7OFwtqnnwfYgyJSEcJIjr2VIy_Ez1hYqlU,859
47
47
  emerge/_emerge/geo/pcb_tools/dxf.py,sha256=Xv7iP_bB0f2Y46sxZloa5KYGyj5dtApXoR-kgL7KHZA,11744
@@ -54,17 +54,17 @@ emerge/_emerge/mth/pairing.py,sha256=i8bBvTeMmzgF0JdiDNJiTXxx913x4f10777pzD6FJo0
54
54
  emerge/_emerge/physics/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
55
55
  emerge/_emerge/physics/microwave/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
56
56
  emerge/_emerge/physics/microwave/adaptive_freq.py,sha256=aWhijhCVAbnuwkru-I1AaRdY20uyozf6OWRIh9r2ijg,9786
57
- emerge/_emerge/physics/microwave/microwave_3d.py,sha256=FYUczByjAVTR3F15B2S1u7KPbYv4oABEqcj-uxemlGY,44396
58
- emerge/_emerge/physics/microwave/microwave_bc.py,sha256=n8lO-jUCKyQfsXVTWgFASxa3EcoFYz5uKXm-WiDKvIY,43655
59
- emerge/_emerge/physics/microwave/microwave_data.py,sha256=CwFg7lukrN5KrgCo-kZT6jSwqbU3I2xC5Xo621zm2Rk,49639
57
+ emerge/_emerge/physics/microwave/microwave_3d.py,sha256=mnfD6QPNVqtMMayu73yRdvErqL2-mPSqiKbOte9a3GQ,44632
58
+ emerge/_emerge/physics/microwave/microwave_bc.py,sha256=bMV3SrIE5BNTdBbTncwy0N67TERsYWzzFypzFgDBW54,43697
59
+ emerge/_emerge/physics/microwave/microwave_data.py,sha256=yAjWGzpTa14JfYKJVMMwx3ETONK_mjYRz98iDKEdDk8,49893
60
60
  emerge/_emerge/physics/microwave/periodic.py,sha256=wYSUgLFVtCLqSG3EDKoCDRU93iPUzBdXzVRdHTRmbpI,3000
61
61
  emerge/_emerge/physics/microwave/port_functions.py,sha256=d-W1D-7P05MfXdOs7WlhPi_RqlSpC0HkYU6yl3GrxgE,2173
62
62
  emerge/_emerge/physics/microwave/sc.py,sha256=WZvoPhmHkfEv619RhmN09sXDBV0ryTqybwErA8Rc7lU,4735
63
63
  emerge/_emerge/physics/microwave/simjob.py,sha256=aCWCs7IXBfVBWWYhwyHvXSRHY3FOd3CK5ABcaFEsNnM,4927
64
64
  emerge/_emerge/physics/microwave/sparam.py,sha256=1SXGyr1UsrPnCIi4ffwobM4pzgkj50y4LrWCr_J5IRY,4946
65
65
  emerge/_emerge/physics/microwave/touchstone.py,sha256=pMcCOLWVqIKctcShcJxyaV-0rhRWXMSS1Jz14dVQEyY,5799
66
- emerge/_emerge/physics/microwave/assembly/assembler.py,sha256=cHmWu5NOCPXbXPK1BkiHAUSvVOYs6aP-44GF7RuRTXA,23926
67
- emerge/_emerge/physics/microwave/assembly/curlcurl.py,sha256=ksK7CcRrix2FMTXwV5SCVKcRcyfih39qhR6brqmt7ds,18663
66
+ emerge/_emerge/physics/microwave/assembly/assembler.py,sha256=sNsAa2bTSe9-tYMRePTOE2EKrqZhsJChD_anr4GC4Vo,23936
67
+ emerge/_emerge/physics/microwave/assembly/curlcurl.py,sha256=4CwMSUua8pvbp39gq2e3AxwVHOIVuPdr53qQM2BigQo,19688
68
68
  emerge/_emerge/physics/microwave/assembly/generalized_eigen.py,sha256=7jNU_hWd7q-ni53wmlhB5kmyJxp2xsx_WyBXZ6hPwo0,16907
69
69
  emerge/_emerge/physics/microwave/assembly/generalized_eigen_hb.py,sha256=tGf9EOzmp-dqtTodwYzcswuT_eLeZRtgdAZvgPz9QJo,17340
70
70
  emerge/_emerge/physics/microwave/assembly/periodicbc.py,sha256=N64uGx49Qs0PJxi_EH5pLx0zcrgJxqMy6DI1TqVXfmQ,4645
@@ -76,7 +76,7 @@ emerge/_emerge/plot/simple_plots.py,sha256=szIpmQmO8o6ubzB_E3zTJfEx16mJ3-OXrMYdD
76
76
  emerge/_emerge/plot/matplotlib/mpldisplay.py,sha256=e8V6EhGdCW7nRkSFvjHCcRO5uR-FcD0yHQ1nxPQCbp4,8674
77
77
  emerge/_emerge/plot/pyvista/__init__.py,sha256=CPclatEu6mFnJZzCQk09g6T6Fh20WTbiLAJGSwAnPXU,30
78
78
  emerge/_emerge/plot/pyvista/cmap_maker.py,sha256=_GVXYdtXpJwAO9O-Iekjzn6YcR0MVT8LNh12nqvF2IA,2498
79
- emerge/_emerge/plot/pyvista/display.py,sha256=IemCSptqlO7EfUZnLNetGiVxn0CgLD8qJ5B9SNTxCOo,41704
79
+ emerge/_emerge/plot/pyvista/display.py,sha256=k5hkIGZCyzYXw1zdDtWCDRwm2dwO0Xz8Sw9YTGGPo5k,45356
80
80
  emerge/_emerge/plot/pyvista/display_settings.py,sha256=gV5hjRGEAl3oQeBPobas6b6JzYfMFrXIGtVSaeml4N0,1074
81
81
  emerge/_emerge/projects/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
82
82
  emerge/_emerge/projects/_gen_base.txt,sha256=DqQz36PZg6v1ovQjHvPjd0t4AIbmikZdb9dmrNYsK3w,598
@@ -88,8 +88,8 @@ emerge/beta/dxf.py,sha256=Bw4lVk0TquOgCxTZV23BZN7PrgqxBrMZxbHV1waC5U0,50
88
88
  emerge/materials/__init__.py,sha256=Z9tu3m_nqj6F9I-FwoVoN0vCTYUlFesH3KxJ38wkZck,19
89
89
  emerge/materials/isola.py,sha256=kSDxHJZVn2CcanoUjlwRVKIPvadRbBybURTdIHWx728,18660
90
90
  emerge/materials/rogers.py,sha256=4u6ma_XQdXGKWE3WsFkaMTamCQNo9kTYSTU8S1gCAYU,3388
91
- emerge-1.0.4.dist-info/METADATA,sha256=AaEHuRZDRdnr-OyyDKli2libsKPtis2OmCRB33Uak-g,3282
92
- emerge-1.0.4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
93
- emerge-1.0.4.dist-info/entry_points.txt,sha256=8rFvAXticpKg4OTC8JEvAksnduW72KIEskCGG9XnFf8,43
94
- emerge-1.0.4.dist-info/licenses/LICENSE,sha256=VOCXWddrjMN5j7TvnSAOh1Dx7jkugdwq9Lqhycf5inc,17852
95
- emerge-1.0.4.dist-info/RECORD,,
91
+ emerge-1.0.6.dist-info/METADATA,sha256=wJysFFkQJJgPoC2pdAtzEvWLsMPB-usHAQweDuNwPqk,3306
92
+ emerge-1.0.6.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
93
+ emerge-1.0.6.dist-info/entry_points.txt,sha256=8rFvAXticpKg4OTC8JEvAksnduW72KIEskCGG9XnFf8,43
94
+ emerge-1.0.6.dist-info/licenses/LICENSE,sha256=VOCXWddrjMN5j7TvnSAOh1Dx7jkugdwq9Lqhycf5inc,17852
95
+ emerge-1.0.6.dist-info/RECORD,,
File without changes