19
19
from ..tools .cache import CachedAttribute
20
20
from ..tools .cache import CachedMethod
21
21
from ..tools .cache import CachedClass
22
- from ..tools import jacobi
23
22
from ..tools import clenshaw
24
23
from ..tools .array import reshape_vector , axindex , axslice , interleave_matrices
25
24
from ..tools .dispatch import MultiClass , SkipDispatchException
26
25
from ..tools .general import unify , DeferredTuple
27
26
28
- from .spaces import ParityInterval , Disk
29
27
from .coords import Coordinate , CartesianCoordinates , S2Coordinates , SphericalCoordinates , PolarCoordinates , AzimuthalCoordinate
30
28
from .domain import Domain
31
29
from .field import Operand , LockedField
@@ -478,23 +476,19 @@ def __init__(self, coord, size, bounds, a, b, a0=None, b0=None, dealias=1, libra
478
476
self .b0 = float (b0 )
479
477
self .library = library
480
478
self .grid_params = (coord , bounds , a0 , b0 )
481
- self .constant_mode_value = 1 / np .sqrt (jacobi .mass (self .a , self .b ))
479
+ self .constant_mode_value = ( 1 / np .sqrt (dedalus_sphere . jacobi .mass (self .a , self .b ))). astype ( np . float64 )
482
480
483
481
def _native_grid (self , scale ):
484
482
"""Native flat global grid."""
485
483
N , = self .grid_shape ((scale ,))
486
- return jacobi .build_grid (N , a = self .a0 , b = self .b0 )
484
+ grid , weights = dedalus_sphere .jacobi .quadrature (N , self .a0 , self .b0 )
485
+ return grid .astype (np .float64 )
487
486
488
487
@CachedMethod
489
488
def transform_plan (self , grid_size ):
490
489
"""Build transform plan."""
491
490
return self .transforms [self .library ](grid_size , self .size , self .a , self .b , self .a0 , self .b0 )
492
491
493
- # def weights(self, scales):
494
- # """Gauss-Jacobi weights."""
495
- # N = self.grid_shape(scales)[0]
496
- # return jacobi.build_weights(N, a=self.a, b=self.b)
497
-
498
492
# def __str__(self):
499
493
# space = self.space
500
494
# cls = self.__class__
@@ -556,14 +550,30 @@ def Jacobi_matrix(self, size):
556
550
size = self .size
557
551
return dedalus_sphere .jacobi .operator ('Z' )(size , self .a , self .b ).square
558
552
553
+ @staticmethod
554
+ def conversion_matrix (N , a0 , b0 , a1 , b1 ):
555
+ if not float (a1 - a0 ).is_integer ():
556
+ raise ValueError ("a0 and a1 must be integer-separated" )
557
+ if not float (b1 - b0 ).is_integer ():
558
+ raise ValueError ("b0 and b1 must be integer-separated" )
559
+ if a0 > a1 :
560
+ raise ValueError ("a0 must be less than or equal to a1" )
561
+ if b0 > b1 :
562
+ raise ValueError ("b0 must be less than or equal to b1" )
563
+ A = dedalus_sphere .jacobi .operator ('A' )(+ 1 )
564
+ B = dedalus_sphere .jacobi .operator ('B' )(+ 1 )
565
+ da , db = int (a1 - a0 ), int (b1 - b0 )
566
+ conv = A ** da @ B ** db
567
+ return conv (N , a0 , b0 ).astype (np .float64 )
568
+
559
569
def ncc_matrix (self , arg_basis , coeffs , cutoff = 1e-6 ):
560
570
"""Build NCC matrix via Clenshaw algorithm."""
561
571
if arg_basis is None :
562
572
return super ().ncc_matrix (arg_basis , coeffs )
563
573
# Kronecker Clenshaw on argument Jacobi matrix
564
574
elif isinstance (arg_basis , Jacobi ):
565
575
N = self .size
566
- J = jacobi .jacobi_matrix ( N , arg_basis .a , arg_basis .b )
576
+ J = dedalus_sphere . jacobi .operator ( 'Z' )( N , arg_basis .a , arg_basis .b ). square . astype ( np . float64 )
567
577
A , B = clenshaw .jacobi_recursion (N , self .a , self .b , J )
568
578
f0 = self .const * sparse .identity (N )
569
579
total = clenshaw .kronecker_clenshaw (coeffs , A , B , f0 , cutoff = cutoff )
@@ -595,7 +605,7 @@ def _last_axis_component_ncc_matrix(cls, subproblem, ncc_basis, arg_basis, out_b
595
605
A , B = clenshaw .jacobi_recursion (Nmat , a_ncc , b_ncc , J )
596
606
f0 = dedalus_sphere .jacobi .polynomials (1 , a_ncc , b_ncc , 1 )[0 ].astype (np .float64 ) * sparse .identity (Nmat )
597
607
matrix = clenshaw .matrix_clenshaw (coeffs .ravel (), A , B , f0 , cutoff = cutoff )
598
- convert = jacobi .conversion_matrix (Nmat , arg_basis .a , arg_basis .b , out_basis .a , out_basis .b )
608
+ convert = Jacobi .conversion_matrix (Nmat , arg_basis .a , arg_basis .b , out_basis .a , out_basis .b )
599
609
matrix = convert @ matrix
600
610
return matrix [:N , :N ]
601
611
@@ -647,7 +657,7 @@ def _full_matrix(input_basis, output_basis):
647
657
N = input_basis .size
648
658
a0 , b0 = input_basis .a , input_basis .b
649
659
a1 , b1 = output_basis .a , output_basis .b
650
- matrix = jacobi .conversion_matrix (N , a0 , b0 , a1 , b1 )
660
+ matrix = Jacobi .conversion_matrix (N , a0 , b0 , a1 , b1 )
651
661
return matrix .tocsr ()
652
662
653
663
@@ -686,8 +696,9 @@ def _output_basis(input_basis):
686
696
def _full_matrix (input_basis , output_basis ):
687
697
N = input_basis .size
688
698
a , b = input_basis .a , input_basis .b
689
- matrix = jacobi .differentiation_matrix (N , a , b ) / input_basis .COV .stretch
690
- return matrix .tocsr ()
699
+ native_matrix = dedalus_sphere .jacobi .operator ('D' )(+ 1 )(N , a , b ).square .astype (np .float64 )
700
+ problem_matrix = native_matrix / input_basis .COV .stretch
701
+ return problem_matrix .tocsr ()
691
702
692
703
693
704
class InterpolateJacobi (operators .Interpolate , operators .SpectralOperator1D ):
@@ -709,9 +720,9 @@ def _full_matrix(input_basis, output_basis, position):
709
720
N = input_basis .size
710
721
a , b = input_basis .a , input_basis .b
711
722
x = input_basis .COV .native_coord (position )
712
- interp_vector = jacobi . build_polynomials ( N , a , b , x )
713
- # Return with shape (1, N)
714
- return interp_vector [ None , :]
723
+ x = np . array ([ x ] )
724
+ matrix = dedalus_sphere . jacobi . polynomials ( N , a , b , x ). T
725
+ return matrix . astype ( np . float64 )
715
726
716
727
717
728
class IntegrateJacobi (operators .Integrate , operators .SpectralOperator1D ):
@@ -731,7 +742,7 @@ def _full_matrix(input_basis, output_basis):
731
742
# Build native integration vector
732
743
N = input_basis .size
733
744
a , b = input_basis .a , input_basis .b
734
- integ_vector = jacobi .integration_vector (N , a , b )
745
+ integ_vector = dedalus_sphere . jacobi .polynomial_integrals (N , a , b ). astype ( np . float64 )
735
746
# Rescale and return with shape (1, N)
736
747
return integ_vector [None , :] * input_basis .COV .stretch
737
748
@@ -753,7 +764,7 @@ def _full_matrix(input_basis, output_basis):
753
764
# Build native integration vector
754
765
N = input_basis .size
755
766
a , b = input_basis .a , input_basis .b
756
- integ_vector = jacobi .integration_vector (N , a , b )
767
+ integ_vector = dedalus_sphere . jacobi .polynomial_integrals (N , a , b ). astype ( np . float64 )
757
768
ave_vector = integ_vector / 2
758
769
# Rescale and return with shape (1, N)
759
770
return ave_vector [None , :]
0 commit comments