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
25
24
from ..tools .dispatch import MultiClass , SkipDispatchException
26
25
from ..tools .general import unify
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
@@ -435,23 +433,19 @@ def __init__(self, coord, size, bounds, a, b, a0=None, b0=None, dealias=1, libra
435
433
self .b0 = float (b0 )
436
434
self .library = library
437
435
self .grid_params = (coord , bounds , a0 , b0 )
438
- self .constant_mode_value = 1 / np .sqrt (jacobi .mass (self .a , self .b ))
436
+ self .constant_mode_value = ( 1 / np .sqrt (dedalus_sphere . jacobi .mass (self .a , self .b ))). astype ( np . float64 )
439
437
440
438
def _native_grid (self , scale ):
441
439
"""Native flat global grid."""
442
440
N , = self .grid_shape ((scale ,))
443
- return jacobi .build_grid (N , a = self .a0 , b = self .b0 )
441
+ grid , weights = dedalus_sphere .jacobi .quadrature (N , self .a0 , self .b0 )
442
+ return grid .astype (np .float64 )
444
443
445
444
@CachedMethod
446
445
def transform_plan (self , grid_size ):
447
446
"""Build transform plan."""
448
447
return self .transforms [self .library ](grid_size , self .size , self .a , self .b , self .a0 , self .b0 )
449
448
450
- # def weights(self, scales):
451
- # """Gauss-Jacobi weights."""
452
- # N = self.grid_shape(scales)[0]
453
- # return jacobi.build_weights(N, a=self.a, b=self.b)
454
-
455
449
# def __str__(self):
456
450
# space = self.space
457
451
# cls = self.__class__
@@ -513,14 +507,30 @@ def Jacobi_matrix(self, size):
513
507
size = self .size
514
508
return dedalus_sphere .jacobi .operator ('Z' )(size , self .a , self .b ).square
515
509
510
+ @staticmethod
511
+ def conversion_matrix (N , a0 , b0 , a1 , b1 ):
512
+ if not float (a1 - a0 ).is_integer ():
513
+ raise ValueError ("a0 and a1 must be integer-separated" )
514
+ if not float (b1 - b0 ).is_integer ():
515
+ raise ValueError ("b0 and b1 must be integer-separated" )
516
+ if a0 > a1 :
517
+ raise ValueError ("a0 must be less than or equal to a1" )
518
+ if b0 > b1 :
519
+ raise ValueError ("b0 must be less than or equal to b1" )
520
+ A = dedalus_sphere .jacobi .operator ('A' )(+ 1 )
521
+ B = dedalus_sphere .jacobi .operator ('B' )(+ 1 )
522
+ da , db = int (a1 - a0 ), int (b1 - b0 )
523
+ conv = A ** da @ B ** db
524
+ return conv (N , a0 , b0 ).astype (np .float64 )
525
+
516
526
def ncc_matrix (self , arg_basis , coeffs , cutoff = 1e-6 ):
517
527
"""Build NCC matrix via Clenshaw algorithm."""
518
528
if arg_basis is None :
519
529
return super ().ncc_matrix (arg_basis , coeffs )
520
530
# Kronecker Clenshaw on argument Jacobi matrix
521
531
elif isinstance (arg_basis , Jacobi ):
522
532
N = self .size
523
- J = jacobi .jacobi_matrix ( N , arg_basis .a , arg_basis .b )
533
+ J = dedalus_sphere . jacobi .operator ( 'Z' )( N , arg_basis .a , arg_basis .b ). square . astype ( np . float64 )
524
534
A , B = clenshaw .jacobi_recursion (N , self .a , self .b , J )
525
535
f0 = self .const * sparse .identity (N )
526
536
total = clenshaw .kronecker_clenshaw (coeffs , A , B , f0 , cutoff = cutoff )
@@ -552,7 +562,7 @@ def multiplication_matrix(self, subproblem, arg_basis, coeffs, ncc_comp, arg_com
552
562
A , B = clenshaw .jacobi_recursion (Nmat , a_ncc , b_ncc , J )
553
563
f0 = dedalus_sphere .jacobi .polynomials (1 , a_ncc , b_ncc , 1 )[0 ].astype (np .float64 ) * sparse .identity (Nmat )
554
564
matrix = clenshaw .matrix_clenshaw (coeffs .ravel (), A , B , f0 , cutoff = cutoff )
555
- convert = jacobi .conversion_matrix (Nmat , arg_basis .a , arg_basis .b , out_basis .a , out_basis .b )
565
+ convert = Jacobi .conversion_matrix (Nmat , arg_basis .a , arg_basis .b , out_basis .a , out_basis .b )
556
566
matrix = convert @ matrix
557
567
return matrix [:N , :N ]
558
568
@@ -604,7 +614,7 @@ def _full_matrix(input_basis, output_basis):
604
614
N = input_basis .size
605
615
a0 , b0 = input_basis .a , input_basis .b
606
616
a1 , b1 = output_basis .a , output_basis .b
607
- matrix = jacobi .conversion_matrix (N , a0 , b0 , a1 , b1 )
617
+ matrix = Jacobi .conversion_matrix (N , a0 , b0 , a1 , b1 )
608
618
return matrix .tocsr ()
609
619
610
620
@@ -643,8 +653,9 @@ def _output_basis(input_basis):
643
653
def _full_matrix (input_basis , output_basis ):
644
654
N = input_basis .size
645
655
a , b = input_basis .a , input_basis .b
646
- matrix = jacobi .differentiation_matrix (N , a , b ) / input_basis .COV .stretch
647
- return matrix .tocsr ()
656
+ native_matrix = dedalus_sphere .jacobi .operator ('D' )(+ 1 )(N , a , b ).square .astype (np .float64 )
657
+ problem_matrix = native_matrix / input_basis .COV .stretch
658
+ return problem_matrix .tocsr ()
648
659
649
660
650
661
class InterpolateJacobi (operators .Interpolate , operators .SpectralOperator1D ):
@@ -666,9 +677,9 @@ def _full_matrix(input_basis, output_basis, position):
666
677
N = input_basis .size
667
678
a , b = input_basis .a , input_basis .b
668
679
x = input_basis .COV .native_coord (position )
669
- interp_vector = jacobi . build_polynomials ( N , a , b , x )
670
- # Return with shape (1, N)
671
- return interp_vector [ None , :]
680
+ x = np . array ([ x ] )
681
+ matrix = dedalus_sphere . jacobi . polynomials ( N , a , b , x ). T
682
+ return matrix . astype ( np . float64 )
672
683
673
684
674
685
class IntegrateJacobi (operators .Integrate , operators .SpectralOperator1D ):
@@ -688,7 +699,7 @@ def _full_matrix(input_basis, output_basis):
688
699
# Build native integration vector
689
700
N = input_basis .size
690
701
a , b = input_basis .a , input_basis .b
691
- integ_vector = jacobi .integration_vector (N , a , b )
702
+ integ_vector = dedalus_sphere . jacobi .polynomial_integrals (N , a , b ). astype ( np . float64 )
692
703
# Rescale and return with shape (1, N)
693
704
return integ_vector [None , :] * input_basis .COV .stretch
694
705
@@ -710,7 +721,7 @@ def _full_matrix(input_basis, output_basis):
710
721
# Build native integration vector
711
722
N = input_basis .size
712
723
a , b = input_basis .a , input_basis .b
713
- integ_vector = jacobi .integration_vector (N , a , b )
724
+ integ_vector = dedalus_sphere . jacobi .polynomial_integrals (N , a , b ). astype ( np . float64 )
714
725
ave_vector = integ_vector / 2
715
726
# Rescale and return with shape (1, N)
716
727
return ave_vector [None , :]
0 commit comments