emerge 1.0.5__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,6 +90,7 @@ 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():
@@ -117,6 +118,7 @@ class SolveReport:
117
118
  parts.append(fmt("DOFsSolve", self.ndof_solve))
118
119
  parts.append(fmt("NNZSolve", self.nnz_solve))
119
120
  parts.append(fmt("Exit", self.exit_code))
121
+ parts.append(fmt("Worker",self.worker_name))
120
122
 
121
123
  if self.aux:
122
124
  for k, v in self.aux.items():
@@ -159,6 +161,7 @@ class SolveReport:
159
161
  row("DOFs (Solve)", self.ndof_solve)
160
162
  row("NNZ (Solve)", self.nnz_solve)
161
163
  row("Exit Code", self.exit_code)
164
+ row("Worker", self.worker_name)
162
165
  print_cal(border)
163
166
 
164
167
  if self.aux:
@@ -168,6 +171,8 @@ class SolveReport:
168
171
  row(str(k), v)
169
172
  print_cal(border)
170
173
 
174
+ def _pfx(name: str, id: int = 0) -> str:
175
+ return f'[{name}-j{id:03d}]'
171
176
  ############################################################
172
177
  # EIGENMODE FILTER ROUTINE #
173
178
  ############################################################
@@ -326,9 +331,10 @@ class Solver:
326
331
  req_sorter: bool = False
327
332
  released_gil: bool = False
328
333
 
329
- def __init__(self):
334
+ def __init__(self, pre: str = ''):
330
335
  self.own_preconditioner: bool = False
331
336
  self.initialized: bool = False
337
+ self.pre: str = pre
332
338
 
333
339
  def __str__(self) -> str:
334
340
  return f'{self.__class__.__name__}'
@@ -364,8 +370,9 @@ class EigSolver:
364
370
  real_only: bool = False
365
371
  req_sorter: bool = False
366
372
 
367
- def __init__(self):
373
+ def __init__(self, pre: str = ''):
368
374
  self.own_preconditioner: bool = False
375
+ self.pre: str = pre
369
376
 
370
377
  def initialize(self) -> None:
371
378
  return None
@@ -374,7 +381,7 @@ class EigSolver:
374
381
  return f'{self.__class__.__name__}'
375
382
 
376
383
  def duplicate(self) -> Solver:
377
- return self.__class__()
384
+ return self.__class__(self.pre)
378
385
 
379
386
  def eig(self, A: csr_matrix | csr_matrix, B: csr_matrix | csr_matrix, nmodes: int = 6,
380
387
  target_k0: float = 0.0, which: str = 'LM', sign: float = 1.):
@@ -448,10 +455,10 @@ class SolverBicgstab(Solver):
448
455
 
449
456
  def callback(self, xk):
450
457
  convergence = np.linalg.norm((self.A @ xk - self.b))
451
- logger.info(f'Iteration {convergence:.4f}')
458
+ logger.info(self.pre + f'Iteration {convergence:.4f}')
452
459
 
453
460
  def solve(self, A, b, precon, reuse_factorization: bool = False, id: int = -1) -> tuple[np.ndarray, SolveReport]:
454
- logger.info(f'[ID={id}] Calling BiCGStab.')
461
+ logger.info(f'{_pfx(self.pre,id)} Calling BiCGStab.')
455
462
  self.A = A
456
463
  self.b = b
457
464
  if precon.M is not None:
@@ -470,10 +477,10 @@ class SolverGCROTMK(Solver):
470
477
 
471
478
  def callback(self, xk):
472
479
  convergence = np.linalg.norm((self.A @ xk - self.b))
473
- logger.info(f'Iteration {convergence:.4f}')
480
+ logger.info(self.pre + f'Iteration {convergence:.4f}')
474
481
 
475
482
  def solve(self, A: csr_matrix, b: np.ndarray, precon: Preconditioner, reuse_factorization: bool = False, id: int = -1) -> tuple[np.ndarray, SolveReport]:
476
- 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')
477
484
  self.A = A
478
485
  self.b = b
479
486
  if precon.M is not None:
@@ -496,10 +503,10 @@ class SolverGMRES(Solver):
496
503
 
497
504
  def callback(self, norm):
498
505
  #convergence = np.linalg.norm((self.A @ xk - self.b))
499
- logger.info(f'Iteration {norm:.4f}')
506
+ logger.info(self.pre + f'Iteration {norm:.4f}')
500
507
 
501
508
  def solve(self, A, b, precon, reuse_factorization: bool = False, id: int = -1) -> tuple[np.ndarray, SolveReport]:
502
- logger.info(f'[ID={id}] Calling GMRES Function.')
509
+ logger.info(f'{_pfx(self.pre,id)} Calling GMRES Function.')
503
510
  self.A = A
504
511
  self.b = b
505
512
  if precon.M is not None:
@@ -520,8 +527,8 @@ class SolverSuperLU(Solver):
520
527
  real_only: bool = False
521
528
  released_gil: bool = True
522
529
 
523
- def __init__(self):
524
- super().__init__()
530
+ def __init__(self, pre: str):
531
+ super().__init__(pre)
525
532
  self.atol = 1e-5
526
533
 
527
534
  self.A: np.ndarray = None
@@ -531,7 +538,7 @@ class SolverSuperLU(Solver):
531
538
  self.lu = None
532
539
 
533
540
  def duplicate(self) -> Solver:
534
- new_solver = self.__class__()
541
+ new_solver = self.__class__(self.pre)
535
542
  new_solver._pivoting_threshold = self._pivoting_threshold
536
543
  return new_solver
537
544
 
@@ -541,11 +548,11 @@ class SolverSuperLU(Solver):
541
548
  self._pivoting_threshold = pivoting_threshold
542
549
 
543
550
  def solve(self, A, b, precon, reuse_factorization: bool = False, id: int = -1) -> tuple[np.ndarray, SolveReport]:
544
- logger.info(f'[ID={id}] Calling SuperLU Solver.')
551
+ logger.info(f'{_pfx(self.pre,id)} Calling SuperLU Solver.')
545
552
 
546
553
  self.single = True
547
554
  if not reuse_factorization:
548
- logger.trace('Computing LU-Decomposition')
555
+ logger.trace(self.pre + 'Computing LU-Decomposition')
549
556
  self.lu = splu(A, permc_spec='MMD_AT_PLUS_A', relax=0, diag_pivot_thresh=self._pivoting_threshold, options=self.options)
550
557
  x = self.lu.solve(b)
551
558
  aux = {
@@ -558,9 +565,9 @@ class SolverUMFPACK(Solver):
558
565
  req_sorter = False
559
566
  real_only = False
560
567
 
561
- def __init__(self):
562
- super().__init__()
563
- logger.trace('Creating UMFPACK solver')
568
+ def __init__(self, pre: str):
569
+ super().__init__(pre)
570
+ logger.trace(self.pre + 'Creating UMFPACK solver')
564
571
  self.A: np.ndarray = None
565
572
  self.b: np.ndarray = None
566
573
 
@@ -575,7 +582,7 @@ class SolverUMFPACK(Solver):
575
582
  def initialize(self):
576
583
  if self.initalized:
577
584
  return
578
- logger.trace('Initializing UMFPACK Solver')
585
+ logger.trace(self.pre + 'Initializing UMFPACK Solver')
579
586
  self.umfpack = um.UmfpackContext('zl')
580
587
  self.umfpack.control[um.UMFPACK_PRL] = 0 # ty: ignore
581
588
  self.umfpack.control[um.UMFPACK_IRSTEP] = 2 # ty: ignore
@@ -588,7 +595,7 @@ class SolverUMFPACK(Solver):
588
595
  self.initalized = True
589
596
 
590
597
  def reset(self) -> None:
591
- logger.trace('Resetting UMFPACK solver state')
598
+ logger.trace(self.pre + 'Resetting UMFPACK solver state')
592
599
  self.fact_symb = False
593
600
 
594
601
  def set_options(self, pivoting_threshold: float | None = None) -> None:
@@ -599,23 +606,23 @@ class SolverUMFPACK(Solver):
599
606
  self._pivoting_threshold = pivoting_threshold
600
607
 
601
608
  def duplicate(self) -> Solver:
602
- new_solver = self.__class__()
609
+ new_solver = self.__class__(self.pre)
603
610
  new_solver.set_options(pivoting_threshold = self._pivoting_threshold)
604
611
  return new_solver
605
612
 
606
613
  def solve(self, A, b, precon, reuse_factorization: bool = False, id: int = -1) -> tuple[np.ndarray, SolveReport]:
607
- logger.info(f'[ID={id}] Calling UMFPACK Solver.')
614
+ logger.info(f'{_pfx(self.pre,id)} Calling UMFPACK Solver.')
608
615
  A.indptr = A.indptr.astype(np.int64)
609
616
  A.indices = A.indices.astype(np.int64)
610
617
  if self.fact_symb is False:
611
- logger.trace(f'[ID={id}] Executing symbollic factorization.')
618
+ logger.trace(f'{_pfx(self.pre,id)} Executing symbollic factorization.')
612
619
  self.umfpack.symbolic(A)
613
620
  self.fact_symb = True
614
621
  if not reuse_factorization:
615
- logger.trace(f'[ID={id}] Executing numeric factorization.')
622
+ logger.trace(f'{_pfx(self.pre,id)} Executing numeric factorization.')
616
623
  self.umfpack.numeric(A)
617
624
  self.A = A
618
- logger.trace(f'[ID={id}] Solving linear system.')
625
+ logger.trace(f'{_pfx(self.pre,id)} Solving linear system.')
619
626
  x = self.umfpack.solve(um.UMFPACK_A, self.A, b, autoTranspose = False ) # ty: ignore
620
627
  aux = {
621
628
  "Pivoting Threshold": str(self._pivoting_threshold),
@@ -627,8 +634,8 @@ class SolverPardiso(Solver):
627
634
  real_only: bool = False
628
635
  req_sorter: bool = False
629
636
 
630
- def __init__(self):
631
- super().__init__()
637
+ def __init__(self, pre: str):
638
+ super().__init__(pre)
632
639
  self.solver: PardisoInterface | None = None
633
640
  self.fact_symb: bool = False
634
641
  self.A: np.ndarray = None
@@ -641,29 +648,30 @@ class SolverPardiso(Solver):
641
648
  self.initialized = True
642
649
 
643
650
  def solve(self, A, b, precon, reuse_factorization: bool = False, id: int = -1) -> tuple[np.ndarray, SolveReport]:
644
- logger.info(f'[ID={id}] Calling Pardiso Solver')
651
+ logger.info(f'{_pfx(self.pre,id)} Calling Pardiso Solver')
645
652
  if self.fact_symb is False:
646
- logger.trace(f'[ID={id}] Executing symbollic factorization.')
653
+ logger.trace(f'{_pfx(self.pre,id)} Executing symbollic factorization.')
647
654
  self.solver.symbolic(A)
648
655
  self.fact_symb = True
649
656
  if not reuse_factorization:
650
- logger.trace(f'[ID={id}] Executing numeric factorization.')
657
+ logger.trace(f'{_pfx(self.pre,id)} Executing numeric factorization.')
651
658
  self.solver.numeric(A)
652
659
  self.A = A
653
- logger.trace(f'[ID={id}] Solving linear system.')
660
+ logger.trace(f'{_pfx(self.pre,id)} Solving linear system.')
654
661
  x, error = self.solver.solve(A, b)
655
662
  if error != 0:
656
- logger.error(f'[ID={id}] Terminated with error code {error}')
657
- logger.error(self.solver.get_error(error))
658
- 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}')
659
666
  aux = {}
660
667
  return x, SolveReport(solver=str(self), exit_code=error, aux=aux)
661
668
 
662
669
 
663
670
  class SolverCuDSS(Solver):
664
671
  real_only = False
665
- def __init__(self):
666
- super().__init__()
672
+
673
+ def __init__(self, pre: str):
674
+ super().__init__(pre)
667
675
  self._cudss: CuDSSInterface | None = None
668
676
  self.fact_symb: bool = False
669
677
  self.fact_numb: bool = False
@@ -680,18 +688,18 @@ class SolverCuDSS(Solver):
680
688
  self.fact_numb = False
681
689
 
682
690
  def solve(self, A, b, precon, reuse_factorization: bool = False, id: int = -1):
683
- logger.info(f'[ID={id}] Calling cuDSS Solver')
691
+ logger.info(f'{_pfx(self.pre,id)} Calling cuDSS Solver')
684
692
 
685
693
  if self.fact_symb is False:
686
- logger.trace(f'[ID={id}] Starting from symbollic factorization.')
694
+ logger.trace(f'{_pfx(self.pre,id)} Starting from symbollic factorization.')
687
695
  x = self._cudss.from_symbolic(A,b)
688
696
  self.fact_symb = True
689
697
  else:
690
698
  if reuse_factorization:
691
- logger.trace(f'[ID={id}] Solving linear system.')
699
+ logger.trace(f'{_pfx(self.pre,id)} Solving linear system.')
692
700
  x = self._cudss.from_solve(b)
693
701
  else:
694
- logger.trace(f'[ID={id}] Starting from numeric factorization.')
702
+ logger.trace(f'{_pfx(self.pre,id)} Starting from numeric factorization.')
695
703
  x = self._cudss.from_numeric(A,b)
696
704
 
697
705
  return x, SolveReport(solver=str(self), exit_code=0, aux={})
@@ -703,8 +711,6 @@ class SolverCuDSS(Solver):
703
711
 
704
712
  class SolverLAPACK(EigSolver):
705
713
 
706
- def __init__(self):
707
- super().__init__()
708
714
 
709
715
  def eig(self,
710
716
  A: csr_matrix | csr_matrix,
@@ -729,7 +735,7 @@ class SolverLAPACK(EigSolver):
729
735
  lam : (m,) real ndarray eigenvalues (m = n or k)
730
736
  vecs : (n, m) complex ndarray eigenvectors, B-orthonormal (xiᴴ B xj = δij)
731
737
  """
732
- logger.debug('Calling LAPACK eig solver')
738
+ logger.info(f'{_pfx(self.pre)} Calling LAPACK eig solver')
733
739
  lam, vecs = eig(A.toarray(), B.toarray(), overwrite_a=True, overwrite_b=True, check_finite=False)
734
740
  lam, vecs = filter_real_modes(lam, vecs, target_k0, 2, 2, sign=sign)
735
741
  return lam, vecs
@@ -742,8 +748,6 @@ class SolverLAPACK(EigSolver):
742
748
 
743
749
  class SolverARPACK(EigSolver):
744
750
  """ Implements the Scipy ARPACK iterative eigenmode solver."""
745
- def __init__(self):
746
- super().__init__()
747
751
 
748
752
  def eig(self,
749
753
  A: csr_matrix | csr_matrix,
@@ -752,7 +756,7 @@ class SolverARPACK(EigSolver):
752
756
  target_k0: float = 0,
753
757
  which: str = 'LM',
754
758
  sign: float = 1.0) -> tuple[np.ndarray, np.ndarray]:
755
- 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')
756
760
  sigma = sign*(target_k0**2)
757
761
  eigen_values, eigen_modes = eigs(A, k=nmodes, M=B, sigma=sigma, which=which)
758
762
  return eigen_values, eigen_modes
@@ -762,8 +766,8 @@ class SmartARPACK_BMA(EigSolver):
762
766
 
763
767
  The Solver searches in a geometric range around the target wave constant.
764
768
  """
765
- def __init__(self):
766
- super().__init__()
769
+ def __init__(self, pre: str):
770
+ super().__init__(pre)
767
771
  self.symmetric_steps: int = 41
768
772
  self.search_range: float = 2.0
769
773
  self.energy_limit: float = 1e-4
@@ -776,7 +780,7 @@ class SmartARPACK_BMA(EigSolver):
776
780
  which: str = 'LM',
777
781
  sign: float = 1.) -> tuple[np.ndarray, np.ndarray]:
778
782
 
779
- 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)')
780
784
  qs = np.geomspace(1, self.search_range, self.symmetric_steps)
781
785
  tot_eigen_values = []
782
786
  tot_eigen_modes = []
@@ -812,8 +816,8 @@ class SmartARPACK(EigSolver):
812
816
 
813
817
  The Solver searches in a geometric range around the target wave constant.
814
818
  """
815
- def __init__(self):
816
- super().__init__()
819
+ def __init__(self, pre: str):
820
+ super().__init__(pre)
817
821
  self.symmetric_steps: int = 3
818
822
  self.search_range: float = 2.0
819
823
  self.energy_limit: float = 1e-4
@@ -825,7 +829,7 @@ class SmartARPACK(EigSolver):
825
829
  target_k0: float = 0,
826
830
  which: str = 'LM',
827
831
  sign: float = 1.) -> tuple[np.ndarray, np.ndarray]:
828
- 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')
829
833
  qs = np.geomspace(1, self.search_range, self.symmetric_steps)
830
834
  tot_eigen_values = []
831
835
  tot_eigen_modes = []
@@ -875,14 +879,14 @@ class EMSolver(Enum):
875
879
  SMART_ARPACK_BMA = 7
876
880
  CUDSS = 8
877
881
 
878
- def create_solver(self) -> Solver | EigSolver | None:
882
+ def create_solver(self, pre: str) -> Solver | EigSolver | None:
879
883
  if self==EMSolver.UMFPACK and not _UMFPACK_AVAILABLE:
880
884
  return None
881
885
  elif self==EMSolver.PARDISO and not _PARDISO_AVAILABLE:
882
886
  return None
883
887
  if self==EMSolver.CUDSS and not _CUDSS_AVAILABLE:
884
888
  return None
885
- return self._clss()
889
+ return self._clss(pre)
886
890
 
887
891
  @property
888
892
  def _clss(self) -> type[Solver]:
@@ -911,11 +915,15 @@ class SolveRoutine:
911
915
  and goes through a sequence of steps to solve a linear system or find eigenmodes.
912
916
 
913
917
  """
914
- 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
+
915
923
 
916
924
  self.sorter: Sorter = ReverseCuthillMckee()
917
925
  self.precon: Preconditioner = ILUPrecon()
918
- 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}
919
927
  self.solvers = {key: solver for key, solver in self.solvers.items() if solver is not None}
920
928
 
921
929
  self.parallel: Literal['SI','MT','MP'] = 'SI'
@@ -926,8 +934,11 @@ class SolveRoutine:
926
934
  self.use_sorter: bool = False
927
935
  self.use_preconditioner: bool = False
928
936
  self.use_direct: bool = True
937
+
929
938
 
930
-
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
+
931
942
  def __str__(self) -> str:
932
943
  return 'SolveRoutine()'
933
944
 
@@ -940,11 +951,11 @@ class SolveRoutine:
940
951
  Returns:
941
952
  bool: If the solver is legal
942
953
  """
943
- if any(isinstance(solver, solvertype) for solvertype in self.disabled_solver):
944
- 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.')
945
956
  return False
946
957
  if self.parallel=='MT' and not solver.released_gil:
947
- 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')
948
959
  return False
949
960
  return True
950
961
 
@@ -973,9 +984,9 @@ class SolveRoutine:
973
984
  return solver # type: ignore
974
985
  for alternative in self.all_solvers:
975
986
  if self._legal_solver(alternative):
976
- logger.debug(f'Falling back on legal solver: {alternative}')
987
+ logger.debug(self.pre + f'Falling back on legal solver: {alternative}')
977
988
  return alternative
978
- 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}')
979
990
 
980
991
  def duplicate(self) -> SolveRoutine:
981
992
  """Creates a copy of this SolveRoutine class object.
@@ -1013,13 +1024,15 @@ class SolveRoutine:
1013
1024
  """
1014
1025
  for solver in solvers:
1015
1026
  if isinstance(solver, EMSolver):
1016
- self.disabled_solver.append(solver.create_solver().__class__)
1027
+ self.disabled_solver.append(self.solvers[solver])
1017
1028
  else:
1018
- self.disabled_solver.append(solver.__class__)
1029
+ self.disabled_solver.append(solver)
1019
1030
 
1020
1031
  def _configure_routine(self,
1021
1032
  parallel: Literal['SI','MT','MP'] = 'SI',
1022
- smart_search: bool = False) -> SolveRoutine:
1033
+ smart_search: bool = False,
1034
+ thread_nr: int = 0,
1035
+ proc_nr: int = 0) -> SolveRoutine:
1023
1036
  """Configure the solver with the given settings
1024
1037
 
1025
1038
  Args:
@@ -1036,6 +1049,12 @@ class SolveRoutine:
1036
1049
  """
1037
1050
  self.parallel = parallel
1038
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
1039
1058
  return self
1040
1059
 
1041
1060
  def configure(self,
@@ -1175,10 +1194,10 @@ class SolveRoutine:
1175
1194
  bsel = b[solve_ids]
1176
1195
  nnz = Asel.nnz
1177
1196
 
1178
- 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)')
1179
1198
 
1180
1199
  if solver.real_only:
1181
- logger.debug(f'[ID={id}] Converting to real matrix')
1200
+ logger.debug(f'{_pfx(self.pre,id)} Converting to real matrix')
1182
1201
  Asel, bsel = complex_to_real_block(Asel, bsel)
1183
1202
 
1184
1203
  # SORT
@@ -1201,8 +1220,8 @@ class SolveRoutine:
1201
1220
  x_solved, report = solver.solve(Asorted, bsorted, self.precon, reuse_factorization=reuse, id=id)
1202
1221
  end = time.time()
1203
1222
  simtime = end-start
1204
- logger.info(f'[ID={id}] Elapsed time taken: {simtime:.3f} seconds')
1205
- 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')
1206
1225
 
1207
1226
  if self.use_sorter and solver.req_sorter:
1208
1227
  x = self.sorter.unsort(x_solved)
@@ -1210,14 +1229,14 @@ class SolveRoutine:
1210
1229
  x = x_solved
1211
1230
 
1212
1231
  if solver.real_only:
1213
- logger.debug(f'[ID={id}] Converting back to complex matrix')
1232
+ logger.debug(f'{_pfx(self.pre,id)} Converting back to complex matrix')
1214
1233
  x = real_to_complex_block(x)
1215
1234
 
1216
1235
  solution = np.zeros((NF,), dtype=np.complex128)
1217
1236
 
1218
1237
  solution[solve_ids] = x
1219
1238
 
1220
- logger.debug(f'[ID={id}] Solver complete!')
1239
+ logger.debug(f'{_pfx(self.pre,id)} Solver complete!')
1221
1240
  report.jobid = id
1222
1241
  report.sorter = str(sorter)
1223
1242
  report.simtime = simtime
@@ -1226,6 +1245,7 @@ class SolveRoutine:
1226
1245
  report.nnz_solve = Asorted.nnz
1227
1246
  report.ndof_solve = bsorted.shape[0]
1228
1247
  report.precon = precon
1248
+ report.worker_name = self.pre
1229
1249
 
1230
1250
  return solution, report
1231
1251
 
@@ -1262,7 +1282,7 @@ class SolveRoutine:
1262
1282
  NF = A.shape[0]
1263
1283
  NS = solve_ids.shape[0]
1264
1284
 
1265
- logger.debug(f'Removing {NF-NS} prescribed DOFs ({NS} left)')
1285
+ logger.debug(self.pre + f'Removing {NF-NS} prescribed DOFs ({NS} left)')
1266
1286
 
1267
1287
  Asel = A[np.ix_(solve_ids, solve_ids)]
1268
1288
  Bsel = B[np.ix_(solve_ids, solve_ids)]
@@ -1305,7 +1325,7 @@ class SolveRoutine:
1305
1325
  NF = A.shape[0]
1306
1326
  NS = solve_ids.shape[0]
1307
1327
 
1308
- logger.debug(f'Removing {NF-NS} prescribed DOFs ({NS} left)')
1328
+ logger.debug(self.pre + f'Removing {NF-NS} prescribed DOFs ({NS} left)')
1309
1329
 
1310
1330
  Asel = A[np.ix_(solve_ids, solve_ids)]
1311
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.5
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
@@ -1,4 +1,4 @@
1
- emerge/__init__.py,sha256=F-k_d_Y9IKWo7DzANY_2dTgpkz0EKV6L8Kpl8eLoFr8,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=460el1k0gCj8Bt9MMoZMBUXx4YftaTrOvXP0Epmj-Dg,26525
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=z3d0UTFjMkOPlyRi8gOASigKlJ9-1MWsGZfAhGk1xr0,51573
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
40
  emerge/_emerge/geo/operations.py,sha256=WYWfOXWrT0voeKW9U26g-PhQfqJl3ovRQ8uDQXUr7Nc,12459
41
- emerge/_emerge/geo/pcb.py,sha256=Mzn7Lho18Xc7A-XShfWZK9Kop4xlLYONMeRhtKkETJU,57577
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=plDHB-67i9tjFc9Ktiq92MOX9mfaxjvFrBYIumR-Pmg,32441
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.5.dist-info/METADATA,sha256=m6vQVIQM-DWznyMQVEOpllXUdsAjbqp-diEb_qgOOrg,3306
92
- emerge-1.0.5.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
93
- emerge-1.0.5.dist-info/entry_points.txt,sha256=8rFvAXticpKg4OTC8JEvAksnduW72KIEskCGG9XnFf8,43
94
- emerge-1.0.5.dist-info/licenses/LICENSE,sha256=VOCXWddrjMN5j7TvnSAOh1Dx7jkugdwq9Lqhycf5inc,17852
95
- emerge-1.0.5.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