1*37045ce4SJed Brown /* Discretization tools */ 2*37045ce4SJed Brown 3*37045ce4SJed Brown #include <petscdt.h> /*I "petscdt.h" I*/ 4*37045ce4SJed Brown #include <petscblaslapack.h> 5*37045ce4SJed Brown 6*37045ce4SJed Brown #undef __FUNCT__ 7*37045ce4SJed Brown #define __FUNCT__ "PetscDTLegendreEval" 8*37045ce4SJed Brown /*@ 9*37045ce4SJed Brown PetscDTLegendreEval - evaluate Legendre polynomial at points 10*37045ce4SJed Brown 11*37045ce4SJed Brown Not Collective 12*37045ce4SJed Brown 13*37045ce4SJed Brown Input Arguments: 14*37045ce4SJed Brown + npoints - number of spatial points to evaluate at 15*37045ce4SJed Brown . points - array of locations to evaluate at 16*37045ce4SJed Brown . ndegree - number of basis degrees to evaluate 17*37045ce4SJed Brown - degrees - sorted array of degrees to evaluate 18*37045ce4SJed Brown 19*37045ce4SJed Brown Output Arguments: 20*37045ce4SJed Brown + B - row-oriented basis evaluation matrix B[point*ndegree + degree] (dimension npoints*ndegrees, allocated by caller) (or PETSC_NULL) 21*37045ce4SJed Brown . D - row-oriented derivative evaluation matrix (or PETSC_NULL) 22*37045ce4SJed Brown - D2 - row-oriented second derivative evaluation matrix (or PETSC_NULL) 23*37045ce4SJed Brown 24*37045ce4SJed Brown Level: intermediate 25*37045ce4SJed Brown 26*37045ce4SJed Brown .seealso: PetscDTGaussQuadrature() 27*37045ce4SJed Brown @*/ 28*37045ce4SJed Brown PetscErrorCode PetscDTLegendreEval(PetscInt npoints,const PetscReal *points,PetscInt ndegree,const PetscInt *degrees,PetscReal *B,PetscReal *D,PetscReal *D2) 29*37045ce4SJed Brown { 30*37045ce4SJed Brown PetscInt i,maxdegree; 31*37045ce4SJed Brown 32*37045ce4SJed Brown PetscFunctionBegin; 33*37045ce4SJed Brown if (!npoints || !ndegree) PetscFunctionReturn(0); 34*37045ce4SJed Brown maxdegree = degrees[ndegree-1]; 35*37045ce4SJed Brown for (i=0; i<npoints; i++) { 36*37045ce4SJed Brown PetscReal pm1,pm2,pd1,pd2,pdd1,pdd2,x; 37*37045ce4SJed Brown PetscInt j,k; 38*37045ce4SJed Brown x = points[i]; 39*37045ce4SJed Brown pm2 = 0; 40*37045ce4SJed Brown pm1 = 1; 41*37045ce4SJed Brown pd2 = 0; 42*37045ce4SJed Brown pd1 = 0; 43*37045ce4SJed Brown pdd2 = 0; 44*37045ce4SJed Brown pdd1 = 0; 45*37045ce4SJed Brown k = 0; 46*37045ce4SJed Brown if (degrees[k] == 0) { 47*37045ce4SJed Brown if (B) B[i*ndegree+k] = pm1; 48*37045ce4SJed Brown if (D) D[i*ndegree+k] = pd1; 49*37045ce4SJed Brown if (D2) D2[i*ndegree+k] = pdd1; 50*37045ce4SJed Brown k++; 51*37045ce4SJed Brown } 52*37045ce4SJed Brown for (j=1; j<=maxdegree; j++,k++) { 53*37045ce4SJed Brown PetscReal p,d,dd; 54*37045ce4SJed Brown p = ((2*j-1)*x*pm1 - (j-1)*pm2)/j; 55*37045ce4SJed Brown d = pd2 + (2*j-1)*pm1; 56*37045ce4SJed Brown dd = pdd2 + (2*j-1)*pd1; 57*37045ce4SJed Brown pm2 = pm1; 58*37045ce4SJed Brown pm1 = p; 59*37045ce4SJed Brown pd2 = pd1; 60*37045ce4SJed Brown pd1 = d; 61*37045ce4SJed Brown pdd2 = pdd1; 62*37045ce4SJed Brown pdd1 = dd; 63*37045ce4SJed Brown if (degrees[k] == j) { 64*37045ce4SJed Brown if (B) B[i*ndegree+k] = p; 65*37045ce4SJed Brown if (D) D[i*ndegree+k] = d; 66*37045ce4SJed Brown if (D2) D2[i*ndegree+k] = dd; 67*37045ce4SJed Brown } 68*37045ce4SJed Brown } 69*37045ce4SJed Brown } 70*37045ce4SJed Brown PetscFunctionReturn(0); 71*37045ce4SJed Brown } 72*37045ce4SJed Brown 73*37045ce4SJed Brown #undef __FUNCT__ 74*37045ce4SJed Brown #define __FUNCT__ "PetscDTGaussQuadrature" 75*37045ce4SJed Brown /*@ 76*37045ce4SJed Brown PetscDTGaussQuadrature - create Gauss quadrature 77*37045ce4SJed Brown 78*37045ce4SJed Brown Not Collective 79*37045ce4SJed Brown 80*37045ce4SJed Brown Input Arguments: 81*37045ce4SJed Brown + npoints - number of points 82*37045ce4SJed Brown . a - left end of interval (often-1) 83*37045ce4SJed Brown - b - right end of interval (often +1) 84*37045ce4SJed Brown 85*37045ce4SJed Brown Output Arguments: 86*37045ce4SJed Brown + x - quadrature points 87*37045ce4SJed Brown - w - quadrature weights 88*37045ce4SJed Brown 89*37045ce4SJed Brown Level: intermediate 90*37045ce4SJed Brown 91*37045ce4SJed Brown References: 92*37045ce4SJed Brown Golub and Welsch, Calculation of Quadrature Rules, Math. Comp. 23(106), 221--230, 1969. 93*37045ce4SJed Brown 94*37045ce4SJed Brown .seealso: PetscDTLegendreEval() 95*37045ce4SJed Brown @*/ 96*37045ce4SJed Brown PetscErrorCode PetscDTGaussQuadrature(PetscInt npoints,PetscReal a,PetscReal b,PetscReal *x,PetscReal *w) 97*37045ce4SJed Brown { 98*37045ce4SJed Brown PetscErrorCode ierr; 99*37045ce4SJed Brown PetscInt i; 100*37045ce4SJed Brown PetscReal *work; 101*37045ce4SJed Brown PetscScalar *Z; 102*37045ce4SJed Brown #if defined(PETSC_HAVE_COMPLEX) 103*37045ce4SJed Brown char compz[] = "I"; /* compute the eigenvectors of the tridiagonal matrix directly */ 104*37045ce4SJed Brown #else 105*37045ce4SJed Brown char compz[] = "V"; 106*37045ce4SJed Brown #endif 107*37045ce4SJed Brown PetscBLASInt N,LDZ,info; 108*37045ce4SJed Brown 109*37045ce4SJed Brown PetscFunctionBegin; 110*37045ce4SJed Brown /* Set up the Golub-Welsch system */ 111*37045ce4SJed Brown for (i=0; i<npoints; i++) { 112*37045ce4SJed Brown x[i] = 0; /* diagonal is 0 */ 113*37045ce4SJed Brown if (i) w[i-1] = 0.5 / PetscSqrtReal(1 - 1./PetscSqr(2*i)); 114*37045ce4SJed Brown } 115*37045ce4SJed Brown ierr = PetscRealView(npoints-1,w,PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); 116*37045ce4SJed Brown ierr = PetscMalloc2(npoints*npoints,PetscScalar,&Z,PetscMax(1,2*npoints-2),PetscReal,&work);CHKERRQ(ierr); 117*37045ce4SJed Brown N = PetscBLASIntCast(npoints); 118*37045ce4SJed Brown LDZ = N; 119*37045ce4SJed Brown ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 120*37045ce4SJed Brown LAPACKstev_(compz,&N,x,w,Z,&LDZ,work,&info); 121*37045ce4SJed Brown ierr = PetscFPTrapPop();CHKERRQ(ierr); 122*37045ce4SJed Brown if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"xSTEV/xSTEQR error"); 123*37045ce4SJed Brown 124*37045ce4SJed Brown for (i=0; i<(npoints+1)/2; i++) { 125*37045ce4SJed Brown PetscReal y = 0.5 * (-x[i] + x[npoints-i-1]); /* enforces symmetry */ 126*37045ce4SJed Brown x[i] = (a+b)/2 - y*(b-a)/2; 127*37045ce4SJed Brown x[npoints-i-1] = (a+b)/2 + y*(b-a)/2; 128*37045ce4SJed Brown w[i] = w[npoints-1-i] = (b-a)*PetscSqr(0.5*PetscAbsScalar(Z[i*npoints] + Z[(npoints-i-1)*npoints])); 129*37045ce4SJed Brown } 130*37045ce4SJed Brown ierr = PetscFree2(Z,work);CHKERRQ(ierr); 131*37045ce4SJed Brown PetscFunctionReturn(0); 132*37045ce4SJed Brown } 133