Nektar++
Functions
Polylib Namespace Reference

The namespace associated with the the Polylib library (Polylib introduction) More...

Functions

double optdiff (double xl, double xr)
 The following function is used to circumvent/reduce "Subtractive Cancellation" The expression 1/dz is replaced by optinvsub(.,.) Added on 26 April 2017. More...
 
double laginterp (double z, int j, const double *zj, int np)
 
double laginterpderiv (double z, int k, const double *zj, int np)
 
static void Jacobz (const int n, double *z, const double alpha, const double beta)
 Calculate the n zeros, z, of the Jacobi polynomial, i.e. \( P_n^{\alpha,\beta}(z) = 0 \). More...
 
static void RecCoeff (const int n, double *a, double *b, const double alpha, const double beta)
 The routine finds the recurrence coefficients a and b of the orthogonal polynomials. More...
 
static void TriQL (const int n, double *d, double *e, double **z)
 QL algorithm for symmetric tridiagonal matrix. More...
 
void JKMatrix (int n, double *a, double *b)
 Calcualtes the Jacobi-kronrod matrix by determining the a and coefficients. More...
 
void chri1 (int n, double *a, double *b, double *a0, double *b0, double z)
 Given a weight function \(w(t)\) through the first n+1 coefficients a and b of its orthogonal polynomials this routine generates the first n recurrence coefficients for the orthogonal polynomials relative to the modified weight function \((t-z)w(t)\). More...
 
void zwgj (double *z, double *w, const int np, const double alpha, const double beta)
 Gauss-Jacobi zeros and weights. More...
 
void zwgrjm (double *z, double *w, const int np, const double alpha, const double beta)
 Gauss-Radau-Jacobi zeros and weights with end point at z=-1. More...
 
void zwgrjp (double *z, double *w, const int np, const double alpha, const double beta)
 Gauss-Radau-Jacobi zeros and weights with end point at z=1. More...
 
void zwglj (double *z, double *w, const int np, const double alpha, const double beta)
 Gauss-Lobatto-Jacobi zeros and weights with end point at z=-1,1. More...
 
void zwgk (double *z, double *w, const int npt, const double alpha, const double beta)
 Gauss-Kronrod-Jacobi zeros and weights. More...
 
void zwrk (double *z, double *w, const int npt, const double alpha, const double beta)
 Gauss-Radau-Kronrod-Jacobi zeros and weights. More...
 
void zwlk (double *z, double *w, const int npt, const double alpha, const double beta)
 Gauss-Lobatto-Kronrod-Jacobi zeros and weights. More...
 
void Qg (double *Q, const double *z, const int np)
 Compute the Integration Matrix. More...
 
void Dgj (double *D, const double *z, const int np, const double alpha, const double beta)
 Compute the Derivative Matrix and its transpose associated with the Gauss-Jacobi zeros. More...
 
void Dgrjm (double *D, const double *z, const int np, const double alpha, const double beta)
 Compute the Derivative Matrix and its transpose associated with the Gauss-Radau-Jacobi zeros with a zero at z=-1. More...
 
void Dgrjp (double *D, const double *z, const int np, const double alpha, const double beta)
 Compute the Derivative Matrix associated with the Gauss-Radau-Jacobi zeros with a zero at z=1. More...
 
void Dglj (double *D, const double *z, const int np, const double alpha, const double beta)
 Compute the Derivative Matrix associated with the Gauss-Lobatto-Jacobi zeros. More...
 
double hgj (const int i, const double z, const double *zgj, const int np, const double alpha, const double beta)
 Compute the value of the i th Lagrangian interpolant through the np Gauss-Jacobi points zgj at the arbitrary location z. More...
 
double hgrjm (const int i, const double z, const double *zgrj, const int np, const double alpha, const double beta)
 Compute the value of the i th Lagrangian interpolant through the np Gauss-Radau-Jacobi points zgrj at the arbitrary location z. This routine assumes zgrj includes the point -1. More...
 
double hgrjp (const int i, const double z, const double *zgrj, const int np, const double alpha, const double beta)
 Compute the value of the i th Lagrangian interpolant through the np Gauss-Radau-Jacobi points zgrj at the arbitrary location z. This routine assumes zgrj includes the point +1. More...
 
double hglj (const int i, const double z, const double *zglj, const int np, const double alpha, const double beta)
 Compute the value of the i th Lagrangian interpolant through the np Gauss-Lobatto-Jacobi points zgrj at the arbitrary location z. More...
 
void Imgj (double *im, const double *zgj, const double *zm, const int nz, const int mz, const double alpha, const double beta)
 Interpolation Operator from Gauss-Jacobi points to an arbitrary distribution at points zm. More...
 
void Imgrjm (double *im, const double *zgrj, const double *zm, const int nz, const int mz, const double alpha, const double beta)
 Interpolation Operator from Gauss-Radau-Jacobi points (including z=-1) to an arbitrary distrubtion at points zm. More...
 
void Imgrjp (double *im, const double *zgrj, const double *zm, const int nz, const int mz, const double alpha, const double beta)
 Interpolation Operator from Gauss-Radau-Jacobi points (including z=1) to an arbitrary distrubtion at points zm. More...
 
void Imglj (double *im, const double *zglj, const double *zm, const int nz, const int mz, const double alpha, const double beta)
 Interpolation Operator from Gauss-Lobatto-Jacobi points to an arbitrary distrubtion at points zm. More...
 
void polycoeffs (double *c, const double *z, const int i, const int np)
 Compute the coefficients of Lagrange interpolation polynomials. More...
 
void jacobfd (const int np, const double *z, double *poly_in, double *polyd, const int n, const double alpha, const double beta)
 Routine to calculate Jacobi polynomials, \( P^{\alpha,\beta}_n(z) \), and their first derivative, \( \frac{d}{dz} P^{\alpha,\beta}_n(z) \). More...
 
void jacobd (const int np, const double *z, double *polyd, const int n, const double alpha, const double beta)
 Calculate the derivative of Jacobi polynomials. More...
 
double gammaF (const double x)
 Calculate the Gamma function , \( \Gamma(n)\), for integer values and halves. More...
 
double gammaFracGammaF (const int x, const double alpha, const int y, const double beta)
 Calculate fraction of two Gamma functions, \( \Gamma(x+\alpha)/\Gamma(y+\beta) \), for integer values and halves. More...
 
std::complex< Nektar::NekDoubleImagBesselComp (int n, std::complex< Nektar::NekDouble > y)
 Calcualte the bessel function of the first kind with complex double input y. Taken from Numerical Recipies in C. More...
 
void JacZeros (const int n, double *a, double *b, const double alpha, const double beta)
 Zero and Weight determination through the eigenvalues and eigenvectors of a tridiagonal matrix from the three term recurrence relationship. More...
 

Detailed Description

The namespace associated with the the Polylib library (Polylib introduction)

Function Documentation

◆ chri1()

void Polylib::chri1 ( int  n,
double *  a,
double *  b,
double *  a0,
double *  b0,
double  z 
)

Given a weight function \(w(t)\) through the first n+1 coefficients a and b of its orthogonal polynomials this routine generates the first n recurrence coefficients for the orthogonal polynomials relative to the modified weight function \((t-z)w(t)\).

The result will be placed in the array a0 and b0.

Definition at line 1860 of file Polylib.cpp.

1861{
1862
1863 double q = ceil(3.0 * n / 2);
1864 int size = (int)q + 1;
1865 if (size < n + 1)
1866 {
1867 fprintf(stderr, "input arrays a and b are too short\n");
1868 }
1869 double *r = new double[n + 1];
1870 r[0] = z - a[0];
1871 r[1] = z - a[1] - b[1] / r[0];
1872 a0[0] = a[1] + r[1] - r[0];
1873 b0[0] = -r[0] * b[0];
1874
1875 if (n == 1)
1876 {
1877 delete[] r;
1878 return;
1879 }
1880 int k = 0;
1881 for (k = 1; k < n; k++)
1882 {
1883 r[k + 1] = z - a[k + 1] - b[k + 1] / r[k];
1884 a0[k] = a[k + 1] + r[k + 1] - r[k];
1885 b0[k] = b[k] * r[k] / r[k - 1];
1886 }
1887 delete[] r;
1888}
std::vector< double > z(NPUPPER)
std::vector< double > q(NPUPPER *NPUPPER)

References Nektar::UnitTests::q(), and Nektar::UnitTests::z().

Referenced by zwlk(), and zwrk().

◆ Dgj()

void Polylib::Dgj ( double *  D,
const double *  z,
const int  np,
const double  alpha,
const double  beta 
)

Compute the Derivative Matrix and its transpose associated with the Gauss-Jacobi zeros.

  • Compute the derivative matrix, d, and its transpose, dt, associated with the n_th order Lagrangian interpolants through the np Gauss-Jacobi points z such that
    \( \frac{du}{dz}(z[i]) = \sum_{j=0}^{np-1} D[i*np+j] u(z[j]) \)

Definition at line 647 of file Polylib.cpp.

649{
650
651 double one = 1.0, two = 2.0;
652
653 if (np <= 0)
654 {
655 D[0] = 0.0;
656 }
657 else
658 {
659 int i, j;
660 double *pd;
661
662 pd = (double *)malloc(np * sizeof(double));
663 jacobd(np, z, pd, np, alpha, beta);
664
665 for (i = 0; i < np; i++)
666 {
667 for (j = 0; j < np; j++)
668 {
669
670 if (i != j)
671 D[i * np + j] = pd[j] / (pd[i] * (z[j] - z[i]));
672 else
673 D[i * np + j] =
674 (alpha - beta + (alpha + beta + two) * z[j]) /
675 (two * (one - z[j] * z[j]));
676 }
677 }
678 free(pd);
679 }
680 return;
681}
@ beta
Gauss Radau pinned at x=-1,.
Definition: PointsType.h:61
void jacobd(const int np, const double *z, double *polyd, const int n, const double alpha, const double beta)
Calculate the derivative of Jacobi polynomials.
Definition: Polylib.cpp:1318

References Nektar::LibUtilities::beta, jacobd(), and Nektar::UnitTests::z().

Referenced by Nektar::UnitTests::BOOST_AUTO_TEST_CASE(), and Nektar::LibUtilities::GaussPoints::v_CalculateDerivMatrix().

◆ Dglj()

void Polylib::Dglj ( double *  D,
const double *  z,
const int  np,
const double  alpha,
const double  beta 
)

Compute the Derivative Matrix associated with the Gauss-Lobatto-Jacobi zeros.

  • Compute the derivative matrix, d, associated with the n_th order Lagrange interpolants through the np Gauss-Lobatto-Jacobi points z such that
    \( \frac{du}{dz}(z[i]) = \sum_{j=0}^{np-1} D[i*np+j] u(z[j]) \)

Definition at line 807 of file Polylib.cpp.

809{
810 if (np <= 1)
811 {
812 D[0] = 0.0;
813 }
814 else
815 {
816 int i, j;
817 double one = 1.0, two = 2.0;
818 double *pd;
819
820 pd = (double *)malloc(np * sizeof(double));
821
822 pd[0] = two * pow(-one, np) * gammaFracGammaF(np, beta, np - 1, 0.0);
823 pd[0] /= gammaF(beta + two);
824 jacobd(np - 2, z + 1, pd + 1, np - 2, alpha + 1, beta + 1);
825 for (i = 1; i < np - 1; ++i)
826 pd[i] *= (one - z[i] * z[i]);
827 pd[np - 1] = -two * gammaFracGammaF(np, alpha, np - 1, 0.0);
828 pd[np - 1] /= gammaF(alpha + two);
829
830 for (i = 0; i < np; i++)
831 {
832 for (j = 0; j < np; j++)
833 {
834 if (i != j)
835 D[i * np + j] = pd[j] / (pd[i] * (z[j] - z[i]));
836 else
837 {
838 if (j == 0)
839 D[i * np + j] =
840 (alpha - (np - 1) * (np + alpha + beta)) /
841 (two * (beta + two));
842 else if (j == np - 1)
843 D[i * np + j] =
844 -(beta - (np - 1) * (np + alpha + beta)) /
845 (two * (alpha + two));
846 else
847 D[i * np + j] = (alpha - beta + (alpha + beta) * z[j]) /
848 (two * (one - z[j] * z[j]));
849 }
850 }
851 }
852 free(pd);
853 }
854
855 return;
856}
double gammaF(const double x)
Calculate the Gamma function , , for integer values and halves.
Definition: Polylib.cpp:1347
double gammaFracGammaF(const int x, const double alpha, const int y, const double beta)
Calculate fraction of two Gamma functions, , for integer values and halves.
Definition: Polylib.cpp:1396

References Nektar::LibUtilities::beta, gammaF(), gammaFracGammaF(), jacobd(), and Nektar::UnitTests::z().

Referenced by Nektar::UnitTests::BOOST_AUTO_TEST_CASE(), and Nektar::LibUtilities::GaussPoints::v_CalculateDerivMatrix().

◆ Dgrjm()

void Polylib::Dgrjm ( double *  D,
const double *  z,
const int  np,
const double  alpha,
const double  beta 
)

Compute the Derivative Matrix and its transpose associated with the Gauss-Radau-Jacobi zeros with a zero at z=-1.

  • Compute the derivative matrix, d, associated with the n_th order Lagrangian interpolants through the np Gauss-Radau-Jacobi points z such that
    \( \frac{du}{dz}(z[i]) = \sum_{j=0}^{np-1} D[i*np+j] u(z[j]) \)

Definition at line 694 of file Polylib.cpp.

696{
697
698 if (np <= 0)
699 {
700 D[0] = 0.0;
701 }
702 else
703 {
704 int i, j;
705 double one = 1.0, two = 2.0;
706 double *pd;
707
708 pd = (double *)malloc(np * sizeof(double));
709
710 pd[0] = pow(-one, np - 1) * gammaFracGammaF(np + 1, beta, np, 0.0);
711 pd[0] /= gammaF(beta + two);
712 jacobd(np - 1, z + 1, pd + 1, np - 1, alpha, beta + 1);
713 for (i = 1; i < np; ++i)
714 pd[i] *= (1 + z[i]);
715
716 for (i = 0; i < np; i++)
717 {
718 for (j = 0; j < np; j++)
719 {
720 if (i != j)
721 D[i * np + j] = pd[j] / (pd[i] * (z[j] - z[i]));
722 else
723 {
724 if (j == 0)
725 D[i * np + j] = -(np + alpha + beta + one) *
726 (np - one) / (two * (beta + two));
727 else
728 D[i * np + j] =
729 (alpha - beta + one + (alpha + beta + one) * z[j]) /
730 (two * (one - z[j] * z[j]));
731 }
732 }
733 }
734 free(pd);
735 }
736
737 return;
738}

References Nektar::LibUtilities::beta, gammaF(), gammaFracGammaF(), jacobd(), and Nektar::UnitTests::z().

Referenced by Nektar::UnitTests::BOOST_AUTO_TEST_CASE(), and Nektar::LibUtilities::GaussPoints::v_CalculateDerivMatrix().

◆ Dgrjp()

void Polylib::Dgrjp ( double *  D,
const double *  z,
const int  np,
const double  alpha,
const double  beta 
)

Compute the Derivative Matrix associated with the Gauss-Radau-Jacobi zeros with a zero at z=1.

  • Compute the derivative matrix, d, associated with the n_th order Lagrangian interpolants through the np Gauss-Radau-Jacobi points z such that
    \( \frac{du}{dz}(z[i]) = \sum_{j=0}^{np-1} D[i*np+j] u(z[j]) \)

Definition at line 750 of file Polylib.cpp.

752{
753
754 if (np <= 0)
755 {
756 D[0] = 0.0;
757 }
758 else
759 {
760 int i, j;
761 double one = 1.0, two = 2.0;
762 double *pd;
763
764 pd = (double *)malloc(np * sizeof(double));
765
766 jacobd(np - 1, z, pd, np - 1, alpha + 1, beta);
767 for (i = 0; i < np - 1; ++i)
768 pd[i] *= (1 - z[i]);
769 pd[np - 1] = -gammaFracGammaF(np + 1, alpha, np, 0.0);
770 pd[np - 1] /= gammaF(alpha + two);
771
772 for (i = 0; i < np; i++)
773 {
774 for (j = 0; j < np; j++)
775 {
776 if (i != j)
777 D[i * np + j] = pd[j] / (pd[i] * (z[j] - z[i]));
778 else
779 {
780 if (j == np - 1)
781 D[i * np + j] = (np + alpha + beta + one) * (np - one) /
782 (two * (alpha + two));
783 else
784 D[i * np + j] =
785 (alpha - beta - one + (alpha + beta + one) * z[j]) /
786 (two * (one - z[j] * z[j]));
787 }
788 }
789 }
790 free(pd);
791 }
792
793 return;
794}

References Nektar::LibUtilities::beta, gammaF(), gammaFracGammaF(), jacobd(), and Nektar::UnitTests::z().

Referenced by Nektar::UnitTests::BOOST_AUTO_TEST_CASE(), and Nektar::LibUtilities::GaussPoints::v_CalculateDerivMatrix().

◆ gammaF()

double Polylib::gammaF ( const double  x)

Calculate the Gamma function , \( \Gamma(n)\), for integer values and halves.

Determine the value of \(\Gamma(n)\) using:

\( \Gamma(n) = (n-1)! \mbox{ or } \Gamma(n+1/2) = (n-1/2)\Gamma(n-1/2)\)

where \( \Gamma(1/2) = \sqrt(\pi)\)

Definition at line 1347 of file Polylib.cpp.

1348{
1349 double gamma = 1.0;
1350
1351 if (x == -0.5)
1352 gamma = -2.0 * sqrt(M_PI);
1353 else if (!x)
1354 return gamma;
1355 else if ((x - (int)x) == 0.5)
1356 {
1357 int n = (int)x;
1358 double tmp = x;
1359
1360 gamma = sqrt(M_PI);
1361 while (n--)
1362 {
1363 tmp -= 1.0;
1364 gamma *= tmp;
1365 }
1366 }
1367 else if ((x - (int)x) == 0.0)
1368 {
1369 int n = (int)x;
1370 double tmp = x;
1371
1372 while (--n)
1373 {
1374 tmp -= 1.0;
1375 gamma *= tmp;
1376 }
1377 }
1378 else
1379 fprintf(stderr, "%lf is not of integer or half order\n", x);
1380 return gamma;
1381}
scalarT< T > sqrt(scalarT< T > in)
Definition: scalar.hpp:294

References tinysimd::sqrt().

Referenced by Nektar::UnitTests::BOOST_AUTO_TEST_CASE(), Dglj(), Dgrjm(), Dgrjp(), and RecCoeff().

◆ gammaFracGammaF()

double Polylib::gammaFracGammaF ( const int  x,
const double  alpha,
const int  y,
const double  beta 
)

Calculate fraction of two Gamma functions, \( \Gamma(x+\alpha)/\Gamma(y+\beta) \), for integer values and halves.

Determine the value of \(\Gamma(n)\) using:

\( \Gamma(n) = (n-1)! \mbox{ or } \Gamma(n+1/2) = (n-1/2)\Gamma(n-1/2)\)

where \( \Gamma(1/2) = \sqrt(\pi)\)

Attempts simplification in cases like \( \Gamma(x+1)/\Gamma(x-1) = x*(x-1) \)

Definition at line 1396 of file Polylib.cpp.

1398{
1399 double gamma = 1.0;
1400 double halfa = fabs(alpha - int(alpha));
1401 double halfb = fabs(beta - int(beta));
1402 if (halfa == 0.0 && halfb == 0.0) // integer value
1403 {
1404 int X = x + alpha;
1405 int Y = y + beta;
1406 if (X > Y)
1407 {
1408 for (int tmp = X - 1; tmp > Y - 1; tmp -= 1)
1409 gamma *= tmp;
1410 }
1411 else if (Y > X)
1412 {
1413 for (int tmp = Y - 1; tmp > X - 1; tmp -= 1)
1414 gamma *= tmp;
1415 gamma = 1. / gamma;
1416 }
1417 }
1418 else if (halfa == 0.5 && halfb == 0.5) // both are halves
1419 {
1420 double X = x + alpha;
1421 double Y = y + beta;
1422 if (X > Y)
1423 {
1424 for (int tmp = int(X); tmp > int(Y); tmp -= 1)
1425 gamma *= tmp - 0.5;
1426 }
1427 else if (Y > X)
1428 {
1429 for (int tmp = int(Y); tmp > int(X); tmp -= 1)
1430 gamma *= tmp - 0.5;
1431 gamma = 1. / gamma;
1432 }
1433 }
1434 else
1435 {
1436 double X = x + alpha;
1437 double Y = y + beta;
1438 while (X > 1 || Y > 1)
1439 {
1440 if (X > 1)
1441 {
1442 gamma *= X - 1.;
1443 X -= 1.;
1444 }
1445 if (Y > 1)
1446 {
1447 gamma /= Y - 1.;
1448 Y -= 1.;
1449 }
1450 }
1451 if (X == 0.5)
1452 {
1453 gamma *= sqrt(M_PI);
1454 }
1455 else if (Y == 0.5)
1456 {
1457 gamma /= sqrt(M_PI);
1458 }
1459 else
1460 {
1461 fprintf(stderr, "%lf or %lf is not of integer or half order\n", X,
1462 Y);
1463 }
1464 }
1465
1466 return gamma;
1467}

References Nektar::LibUtilities::beta, and tinysimd::sqrt().

Referenced by Nektar::UnitTests::BOOST_AUTO_TEST_CASE(), Dglj(), Dgrjm(), Dgrjp(), zwgj(), zwglj(), zwgrjm(), and zwgrjp().

◆ hgj()

double Polylib::hgj ( const int  i,
const double  z,
const double *  zgj,
const int  np,
const double  alpha,
const double  beta 
)

Compute the value of the i th Lagrangian interpolant through the np Gauss-Jacobi points zgj at the arbitrary location z.

  • \( -1 \leq z \leq 1 \)
  • Uses the defintion of the Lagrangian interpolant:
    % \( \begin{array}{rcl} h_j(z) = \left\{ \begin{array}{ll} \displaystyle \frac{P_{np}^{\alpha,\beta}(z)} {[P_{np}^{\alpha,\beta}(z_j)]^\prime (z-z_j)} & \mbox{if $z \ne z_j$}\\ & \\ 1 & \mbox{if $z=z_j$} \end{array} \right. \end{array} \)

Definition at line 878 of file Polylib.cpp.

880{
881 boost::ignore_unused(alpha, beta);
882 double zi, dz;
883
884 zi = *(zgj + i);
885 dz = z - zi;
886 if (fabs(dz) < EPS)
887 return 1.0;
888
889 return laginterp(z, i, zgj, np);
890}
#define EPS
Precision tolerance for two points to be similar.
Definition: Polylib.cpp:47
double laginterp(double z, int j, const double *zj, int np)
Definition: Polylib.cpp:87

References Nektar::LibUtilities::beta, EPS, laginterp(), and Nektar::UnitTests::z().

Referenced by Nektar::LibUtilities::Basis::GenBasis(), Imgj(), and Nektar::LibUtilities::TimeIntegrationSchemeSDC::v_InitializeScheme().

◆ hglj()

double Polylib::hglj ( const int  i,
const double  z,
const double *  zglj,
const int  np,
const double  alpha,
const double  beta 
)

Compute the value of the i th Lagrangian interpolant through the np Gauss-Lobatto-Jacobi points zgrj at the arbitrary location z.

  • \( -1 \leq z \leq 1 \)
  • Uses the defintion of the Lagrangian interpolant:
    % \( \begin{array}{rcl} h_j(z) = \left\{ \begin{array}{ll} \displaystyle \frac{(1-z^2) P_{np-2}^{\alpha+1,\beta+1}(z)} {((1-z^2_j) [P_{np-2}^{\alpha+1,\beta+1}(z_j)]^\prime - 2 z_j P_{np-2}^{\alpha+1,\beta+1}(z_j) ) (z-z_j)}&\mbox{if $z \ne z_j$}\\ & \\ 1 & \mbox{if $z=z_j$} \end{array} \right. \end{array} \)

Definition at line 984 of file Polylib.cpp.

986{
987 boost::ignore_unused(alpha, beta);
988
989 double zi, dz;
990
991 zi = *(zglj + i);
992 dz = z - zi;
993 if (fabs(dz) < EPS)
994 return 1.0;
995
996 return laginterp(z, i, zglj, np);
997}

References Nektar::LibUtilities::beta, EPS, laginterp(), and Nektar::UnitTests::z().

Referenced by Nektar::LibUtilities::Basis::GenBasis(), and Imglj().

◆ hgrjm()

double Polylib::hgrjm ( const int  i,
const double  z,
const double *  zgrj,
const int  np,
const double  alpha,
const double  beta 
)

Compute the value of the i th Lagrangian interpolant through the np Gauss-Radau-Jacobi points zgrj at the arbitrary location z. This routine assumes zgrj includes the point -1.

  • \( -1 \leq z \leq 1 \)
  • Uses the defintion of the Lagrangian interpolant:
    % \( \begin{array}{rcl} h_j(z) = \left\{ \begin{array}{ll} \displaystyle \frac{(1+z) P_{np-1}^{\alpha,\beta+1}(z)} {((1+z_j) [P_{np-1}^{\alpha,\beta+1}(z_j)]^\prime + P_{np-1}^{\alpha,\beta+1}(z_j) ) (z-z_j)} & \mbox{if $z \ne z_j$}\\ & \\ 1 & \mbox{if $z=z_j$} \end{array} \right. \end{array} \)

Definition at line 913 of file Polylib.cpp.

915{
916 boost::ignore_unused(alpha, beta);
917
918 double zi, dz;
919
920 zi = *(zgrj + i);
921 dz = z - zi;
922 if (fabs(dz) < EPS)
923 return 1.0;
924
925 return laginterp(z, i, zgrj, np);
926}

References Nektar::LibUtilities::beta, EPS, laginterp(), and Nektar::UnitTests::z().

Referenced by Imgrjm().

◆ hgrjp()

double Polylib::hgrjp ( const int  i,
const double  z,
const double *  zgrj,
const int  np,
const double  alpha,
const double  beta 
)

Compute the value of the i th Lagrangian interpolant through the np Gauss-Radau-Jacobi points zgrj at the arbitrary location z. This routine assumes zgrj includes the point +1.

  • \( -1 \leq z \leq 1 \)
  • Uses the defintion of the Lagrangian interpolant:
    % \( \begin{array}{rcl} h_j(z) = \left\{ \begin{array}{ll} \displaystyle \frac{(1-z) P_{np-1}^{\alpha+1,\beta}(z)} {((1-z_j) [P_{np-1}^{\alpha+1,\beta}(z_j)]^\prime - P_{np-1}^{\alpha+1,\beta}(z_j) ) (z-z_j)} & \mbox{if $z \ne z_j$}\\ & \\ 1 & \mbox{if $z=z_j$} \end{array} \right. \end{array} \)

Definition at line 949 of file Polylib.cpp.

951{
952 boost::ignore_unused(alpha, beta);
953 double zi, dz;
954
955 zi = *(zgrj + i);
956 dz = z - zi;
957 if (fabs(dz) < EPS)
958 return 1.0;
959
960 return laginterp(z, i, zgrj, np);
961}

References Nektar::LibUtilities::beta, EPS, laginterp(), and Nektar::UnitTests::z().

Referenced by Imgrjp().

◆ ImagBesselComp()

std::complex< Nektar::NekDouble > Polylib::ImagBesselComp ( int  n,
std::complex< Nektar::NekDouble y 
)

Calcualte the bessel function of the first kind with complex double input y. Taken from Numerical Recipies in C.

Returns a complex double

Definition at line 1479 of file Polylib.cpp.

1481{
1482 std::complex<Nektar::NekDouble> z(1.0, 0.0);
1483 std::complex<Nektar::NekDouble> zbes(1.0, 0.0);
1484 std::complex<Nektar::NekDouble> zarg;
1485 Nektar::NekDouble tol = 1e-15;
1486 int maxit = 10000;
1487 int i = 1;
1488
1489 zarg = -0.25 * y * y;
1490
1491 while (abs(z) > tol && i <= maxit)
1492 {
1493 z = z * (1.0 / i / (i + n) * zarg);
1494 if (abs(z) <= tol)
1495 break;
1496 zbes = zbes + z;
1497 i++;
1498 }
1499 zarg = 0.5 * y;
1500 for (i = 1; i <= n; i++)
1501 {
1502 zbes = zbes * zarg;
1503 }
1504 return zbes;
1505}
double NekDouble
scalarT< T > abs(scalarT< T > in)
Definition: scalar.hpp:298

References tinysimd::abs(), and Nektar::UnitTests::z().

Referenced by Nektar::IncNavierStokes::SetUpWomersley().

◆ Imgj()

void Polylib::Imgj ( double *  im,
const double *  zgj,
const double *  zm,
const int  nz,
const int  mz,
const double  alpha,
const double  beta 
)

Interpolation Operator from Gauss-Jacobi points to an arbitrary distribution at points zm.

  • Computes the one-dimensional interpolation matrix, im, to interpolate a function from at Gauss-Jacobi distribution of nz zeros zgrj to an arbitrary distribution of mz points zm, i.e.
    \( u(zm[i]) = \sum_{j=0}^{nz-1} im[i*nz+j] \ u(zgj[j]) \)

Definition at line 1012 of file Polylib.cpp.

1014{
1015 double zp;
1016 int i, j;
1017
1018 for (i = 0; i < nz; ++i)
1019 {
1020 for (j = 0; j < mz; ++j)
1021 {
1022 zp = zm[j];
1023 im[i * mz + j] = hgj(i, zp, zgj, nz, alpha, beta);
1024 }
1025 }
1026
1027 return;
1028}
double hgj(const int i, const double z, const double *zgj, const int np, const double alpha, const double beta)
Compute the value of the i th Lagrangian interpolant through the np Gauss-Jacobi points zgj at the ar...
Definition: Polylib.cpp:878

References Nektar::LibUtilities::beta, and hgj().

Referenced by Nektar::UnitTests::BOOST_AUTO_TEST_CASE(), and Nektar::LibUtilities::GaussPoints::CalculateInterpMatrix().

◆ Imglj()

void Polylib::Imglj ( double *  im,
const double *  zglj,
const double *  zm,
const int  nz,
const int  mz,
const double  alpha,
const double  beta 
)

Interpolation Operator from Gauss-Lobatto-Jacobi points to an arbitrary distrubtion at points zm.

  • Computes the one-dimensional interpolation matrix, im, to interpolate a function from at Gauss-Lobatto-Jacobi distribution of nz zeros zgrj (where zgrj[0]=-1) to an arbitrary distribution of mz points zm, i.e.
    \( u(zm[i]) = \sum_{j=0}^{nz-1} im[i*nz+j] \ u(zgj[j]) \)

Definition at line 1105 of file Polylib.cpp.

1107{
1108 double zp;
1109 int i, j;
1110
1111 for (i = 0; i < nz; i++)
1112 {
1113 for (j = 0; j < mz; j++)
1114 {
1115 zp = zm[j];
1116 im[i * mz + j] = hglj(i, zp, zglj, nz, alpha, beta);
1117 }
1118 }
1119
1120 return;
1121}
double hglj(const int i, const double z, const double *zglj, const int np, const double alpha, const double beta)
Compute the value of the i th Lagrangian interpolant through the np Gauss-Lobatto-Jacobi points zgrj ...
Definition: Polylib.cpp:984

References Nektar::LibUtilities::beta, and hglj().

Referenced by Nektar::UnitTests::BOOST_AUTO_TEST_CASE(), and Nektar::LibUtilities::GaussPoints::CalculateInterpMatrix().

◆ Imgrjm()

void Polylib::Imgrjm ( double *  im,
const double *  zgrj,
const double *  zm,
const int  nz,
const int  mz,
const double  alpha,
const double  beta 
)

Interpolation Operator from Gauss-Radau-Jacobi points (including z=-1) to an arbitrary distrubtion at points zm.

  • Computes the one-dimensional interpolation matrix, im, to interpolate a function from at Gauss-Radau-Jacobi distribution of nz zeros zgrj (where zgrj[0]=-1) to an arbitrary distribution of mz points zm, i.e.
    \( u(zm[i]) = \sum_{j=0}^{nz-1} im[i*nz+j] \ u(zgj[j]) \)

Definition at line 1043 of file Polylib.cpp.

1045{
1046 double zp;
1047 int i, j;
1048
1049 for (i = 0; i < nz; i++)
1050 {
1051 for (j = 0; j < mz; j++)
1052 {
1053 zp = zm[j];
1054 im[i * mz + j] = hgrjm(i, zp, zgrj, nz, alpha, beta);
1055 }
1056 }
1057
1058 return;
1059}
double hgrjm(const int i, const double z, const double *zgrj, const int np, const double alpha, const double beta)
Compute the value of the i th Lagrangian interpolant through the np Gauss-Radau-Jacobi points zgrj at...
Definition: Polylib.cpp:913

References Nektar::LibUtilities::beta, and hgrjm().

Referenced by Nektar::UnitTests::BOOST_AUTO_TEST_CASE(), and Nektar::LibUtilities::GaussPoints::CalculateInterpMatrix().

◆ Imgrjp()

void Polylib::Imgrjp ( double *  im,
const double *  zgrj,
const double *  zm,
const int  nz,
const int  mz,
const double  alpha,
const double  beta 
)

Interpolation Operator from Gauss-Radau-Jacobi points (including z=1) to an arbitrary distrubtion at points zm.

  • Computes the one-dimensional interpolation matrix, im, to interpolate a function from at Gauss-Radau-Jacobi distribution of nz zeros zgrj (where zgrj[nz-1]=1) to an arbitrary distribution of mz points zm, i.e.
    \( u(zm[i]) = \sum_{j=0}^{nz-1} im[i*nz+j] \ u(zgj[j]) \)

Definition at line 1074 of file Polylib.cpp.

1076{
1077 double zp;
1078 int i, j;
1079
1080 for (i = 0; i < nz; i++)
1081 {
1082 for (j = 0; j < mz; j++)
1083 {
1084 zp = zm[j];
1085 im[i * mz + j] = hgrjp(i, zp, zgrj, nz, alpha, beta);
1086 }
1087 }
1088
1089 return;
1090}
double hgrjp(const int i, const double z, const double *zgrj, const int np, const double alpha, const double beta)
Compute the value of the i th Lagrangian interpolant through the np Gauss-Radau-Jacobi points zgrj at...
Definition: Polylib.cpp:949

References Nektar::LibUtilities::beta, and hgrjp().

Referenced by Nektar::UnitTests::BOOST_AUTO_TEST_CASE(), and Nektar::LibUtilities::GaussPoints::CalculateInterpMatrix().

◆ jacobd()

void Polylib::jacobd ( const int  np,
const double *  z,
double *  polyd,
const int  n,
const double  alpha,
const double  beta 
)

Calculate the derivative of Jacobi polynomials.

  • Generates a vector poly of values of the derivative of the n th order Jacobi polynomial \( P^(\alpha,\beta)_n(z)\) at the np points z.
  • To do this we have used the relation
    \( \frac{d}{dz} P^{\alpha,\beta}_n(z) = \frac{1}{2} (\alpha + \beta + n + 1) P^{\alpha,\beta}_n(z) \)
  • This formulation is valid for \( -1 \leq z \leq 1 \)

Definition at line 1318 of file Polylib.cpp.

1320{
1321 int i;
1322 double one = 1.0;
1323 if (n == 0)
1324 for (i = 0; i < np; ++i)
1325 polyd[i] = 0.0;
1326 else
1327 {
1328 // jacobf(np,z,polyd,n-1,alpha+one,beta+one);
1329 jacobfd(np, z, polyd, NULL, n - 1, alpha + one, beta + one);
1330 for (i = 0; i < np; ++i)
1331 polyd[i] *= 0.5 * (alpha + beta + (double)n + one);
1332 }
1333 return;
1334}
void jacobfd(const int np, const double *z, double *poly_in, double *polyd, const int n, const double alpha, const double beta)
Routine to calculate Jacobi polynomials, , and their first derivative, .
Definition: Polylib.cpp:1206

References Nektar::LibUtilities::beta, jacobfd(), and Nektar::UnitTests::z().

Referenced by Dgj(), Dglj(), Dgrjm(), Dgrjp(), Nektar::SolverUtils::AdvectionFR::SetupCFunctions(), Nektar::SolverUtils::DiffusionLFR::SetupCFunctions(), Nektar::SolverUtils::DiffusionLFRNS::SetupCFunctions(), Nektar::LibUtilities::NodalUtilTriangle::v_OrthoBasisDeriv(), Nektar::LibUtilities::NodalUtilTetrahedron::v_OrthoBasisDeriv(), Nektar::LibUtilities::NodalUtilPrism::v_OrthoBasisDeriv(), Nektar::LibUtilities::NodalUtilQuad::v_OrthoBasisDeriv(), Nektar::LibUtilities::NodalUtilHex::v_OrthoBasisDeriv(), and zwgj().

◆ jacobfd()

void Polylib::jacobfd ( const int  np,
const double *  z,
double *  poly_in,
double *  polyd,
const int  n,
const double  alpha,
const double  beta 
)

Routine to calculate Jacobi polynomials, \( P^{\alpha,\beta}_n(z) \), and their first derivative, \( \frac{d}{dz} P^{\alpha,\beta}_n(z) \).

  • This function returns the vectors poly_in and poly_d containing the value of the \( n^th \) order Jacobi polynomial \( P^{\alpha,\beta}_n(z) \alpha > -1, \beta > -1 \) and its derivative at the np points in z[i]
  • If poly_in = NULL then only calculate derivatice
  • If polyd = NULL then only calculate polynomial
  • To calculate the polynomial this routine uses the recursion relationship (see appendix A ref [4]) : \( \begin{array}{rcl} P^{\alpha,\beta}_0(z) &=& 1 \\ P^{\alpha,\beta}_1(z) &=& \frac{1}{2} [ \alpha-\beta+(\alpha+\beta+2)z] \\ a^1_n P^{\alpha,\beta}_{n+1}(z) &=& (a^2_n + a^3_n z) P^{\alpha,\beta}_n(z) - a^4_n P^{\alpha,\beta}_{n-1}(z) \\ a^1_n &=& 2(n+1)(n+\alpha + \beta + 1)(2n + \alpha + \beta) \\ a^2_n &=& (2n + \alpha + \beta + 1)(\alpha^2 - \beta^2) \\ a^3_n &=& (2n + \alpha + \beta)(2n + \alpha + \beta + 1) (2n + \alpha + \beta + 2) \\ a^4_n &=& 2(n+\alpha)(n+\beta)(2n + \alpha + \beta + 2) \end{array} \)
  • To calculate the derivative of the polynomial this routine uses the relationship (see appendix A ref [4]) : \( \begin{array}{rcl} b^1_n(z)\frac{d}{dz} P^{\alpha,\beta}_n(z)&=&b^2_n(z)P^{\alpha,\beta}_n(z) + b^3_n(z) P^{\alpha,\beta}_{n-1}(z) \hspace{2.2cm} \\ b^1_n(z) &=& (2n+\alpha + \beta)(1-z^2) \\ b^2_n(z) &=& n[\alpha - \beta - (2n+\alpha + \beta)z]\\ b^3_n(z) &=& 2(n+\alpha)(n+\beta) \end{array} \)
  • Note the derivative from this routine is only valid for -1 < z < 1.

Definition at line 1206 of file Polylib.cpp.

1208{
1209 int i;
1210 double zero = 0.0, one = 1.0, two = 2.0;
1211
1212 if (!np)
1213 return;
1214
1215 if (n == 0)
1216 {
1217 if (poly_in)
1218 for (i = 0; i < np; ++i)
1219 poly_in[i] = one;
1220 if (polyd)
1221 for (i = 0; i < np; ++i)
1222 polyd[i] = zero;
1223 }
1224 else if (n == 1)
1225 {
1226 if (poly_in)
1227 for (i = 0; i < np; ++i)
1228 poly_in[i] = 0.5 * (alpha - beta + (alpha + beta + two) * z[i]);
1229 if (polyd)
1230 for (i = 0; i < np; ++i)
1231 polyd[i] = 0.5 * (alpha + beta + two);
1232 }
1233 else
1234 {
1235 int k;
1236 double a1, a2, a3, a4;
1237 double two = 2.0, apb = alpha + beta;
1238 double *poly, *polyn1, *polyn2;
1239
1240 if (poly_in)
1241 { // switch for case of no poynomial function return
1242 polyn1 = (double *)malloc(2 * np * sizeof(double));
1243 polyn2 = polyn1 + np;
1244 poly = poly_in;
1245 }
1246 else
1247 {
1248 polyn1 = (double *)malloc(3 * np * sizeof(double));
1249 polyn2 = polyn1 + np;
1250 poly = polyn2 + np;
1251 }
1252
1253 for (i = 0; i < np; ++i)
1254 {
1255 polyn2[i] = one;
1256 polyn1[i] = 0.5 * (alpha - beta + (alpha + beta + two) * z[i]);
1257 }
1258
1259 for (k = 2; k <= n; ++k)
1260 {
1261 a1 = two * k * (k + apb) * (two * k + apb - two);
1262 a2 = (two * k + apb - one) * (alpha * alpha - beta * beta);
1263 a3 =
1264 (two * k + apb - two) * (two * k + apb - one) * (two * k + apb);
1265 a4 = two * (k + alpha - one) * (k + beta - one) * (two * k + apb);
1266
1267 a2 /= a1;
1268 a3 /= a1;
1269 a4 /= a1;
1270
1271 for (i = 0; i < np; ++i)
1272 {
1273 poly[i] = (a2 + a3 * z[i]) * polyn1[i] - a4 * polyn2[i];
1274 polyn2[i] = polyn1[i];
1275 polyn1[i] = poly[i];
1276 }
1277 }
1278
1279 if (polyd)
1280 {
1281 a1 = n * (alpha - beta);
1282 a2 = n * (two * n + alpha + beta);
1283 a3 = two * (n + alpha) * (n + beta);
1284 a4 = (two * n + alpha + beta);
1285 a1 /= a4;
1286 a2 /= a4;
1287 a3 /= a4;
1288
1289 // note polyn2 points to polyn1 at end of poly iterations
1290 for (i = 0; i < np; ++i)
1291 {
1292 polyd[i] = (a1 - a2 * z[i]) * poly[i] + a3 * polyn2[i];
1293 polyd[i] /= (one - z[i] * z[i]);
1294 }
1295 }
1296
1297 free(polyn1);
1298 }
1299
1300 return;
1301}

References Nektar::LibUtilities::beta, and Nektar::UnitTests::z().

Referenced by Nektar::LibUtilities::Basis::GenBasis(), jacobd(), Jacobz(), Nektar::UnitTests::TestIntegral(), Nektar::LibUtilities::NodalUtilTriangle::v_OrthoBasis(), Nektar::LibUtilities::NodalUtilTetrahedron::v_OrthoBasis(), Nektar::LibUtilities::NodalUtilPrism::v_OrthoBasis(), Nektar::LibUtilities::NodalUtilQuad::v_OrthoBasis(), Nektar::LibUtilities::NodalUtilHex::v_OrthoBasis(), Nektar::LibUtilities::NodalUtilTriangle::v_OrthoBasisDeriv(), Nektar::LibUtilities::NodalUtilTetrahedron::v_OrthoBasisDeriv(), Nektar::LibUtilities::NodalUtilPrism::v_OrthoBasisDeriv(), Nektar::LibUtilities::NodalUtilQuad::v_OrthoBasisDeriv(), Nektar::LibUtilities::NodalUtilHex::v_OrthoBasisDeriv(), zwglj(), zwgrjm(), and zwgrjp().

◆ Jacobz()

static void Polylib::Jacobz ( const int  n,
double *  z,
const double  alpha,
const double  beta 
)
static

Calculate the n zeros, z, of the Jacobi polynomial, i.e. \( P_n^{\alpha,\beta}(z) = 0 \).

This routine is only value for \(( \alpha > -1, \beta > -1)\) and uses polynomial deflation in a Newton iteration

Definition at line 1515 of file Polylib.cpp.

1517{
1518 int i, j, k;
1519 double dth = M_PI / (2.0 * (double)n);
1520 double poly, pder, rlast = 0.0;
1521 double sum, delr, r;
1522 double one = 1.0, two = 2.0;
1523
1524 if (!n)
1525 return;
1526
1527 for (k = 0; k < n; ++k)
1528 {
1529 r = -cos((two * (double)k + one) * dth);
1530 if (k)
1531 r = 0.5 * (r + rlast);
1532
1533 for (j = 1; j < STOP; ++j)
1534 {
1535 jacobfd(1, &r, &poly, &pder, n, alpha, beta);
1536
1537 for (i = 0, sum = 0.0; i < k; ++i)
1538 sum += one / (r - z[i]);
1539
1540 delr = -poly / (pder - sum * poly);
1541 r += delr;
1542 if (fabs(delr) < EPS)
1543 break;
1544 }
1545 z[k] = r;
1546 rlast = r;
1547 }
1548 return;
1549}
#define STOP
Maximum number of iterations in polynomial defalation routine Jacobz.
Definition: Polylib.cpp:45

References Nektar::LibUtilities::beta, EPS, jacobfd(), STOP, and Nektar::UnitTests::z().

◆ JacZeros()

void Polylib::JacZeros ( const int  n,
double *  a,
double *  b,
const double  alpha,
const double  beta 
)

Zero and Weight determination through the eigenvalues and eigenvectors of a tridiagonal matrix from the three term recurrence relationship.

Set up a symmetric tridiagonal matrix

\( \left [ \begin{array}{ccccc} a[0] & b[0] & & & \\ b[0] & a[1] & b[1] & & \\ 0 & \ddots & \ddots & \ddots & \\ & & \ddots & \ddots & b[n-2] \\ & & & b[n-2] & a[n-1] \end{array} \right ] \)

Where the coefficients a[n], b[n] come from the recurrence relation

\( b_j p_j(z) = (z - a_j ) p_{j-1}(z) - b_{j-1} p_{j-2}(z) \)

where \( j=n+1\) and \(p_j(z)\) are the Jacobi (normalized) orthogonal polynomials \( \alpha,\beta > -1\)( integer values and halves). Since the polynomials are orthonormalized, the tridiagonal matrix is guaranteed to be symmetric. The eigenvalues of this matrix are the zeros of the Jacobi polynomial.

Definition at line 1575 of file Polylib.cpp.

1577{
1578
1579 int i, j;
1580 RecCoeff(n, a, b, alpha, beta);
1581
1582 double **z = new double *[n];
1583 for (i = 0; i < n; i++)
1584 {
1585 z[i] = new double[n];
1586 for (j = 0; j < n; j++)
1587 {
1588 z[i][j] = 0.0;
1589 }
1590 }
1591 for (i = 0; i < n; i++)
1592 {
1593 z[i][i] = 1.0;
1594 }
1595
1596 // find eigenvalues and eigenvectors
1597 TriQL(n, a, b, z);
1598
1599 delete[] z;
1600 return;
1601}
static void RecCoeff(const int, double *, double *, const double, const double)
The routine finds the recurrence coefficients a and b of the orthogonal polynomials.
Definition: Polylib.cpp:1607
static void TriQL(const int, double *, double *, double **)
QL algorithm for symmetric tridiagonal matrix.
Definition: Polylib.cpp:1666

References Nektar::LibUtilities::beta, RecCoeff(), TriQL(), and Nektar::UnitTests::z().

◆ JKMatrix()

void Polylib::JKMatrix ( int  n,
double *  a,
double *  b 
)

Calcualtes the Jacobi-kronrod matrix by determining the a and coefficients.

The first 3n+1 coefficients are already known

For more information refer to: "Dirk P. Laurie, Calcualtion of Gauss-Kronrod quadrature rules"

Definition at line 1779 of file Polylib.cpp.

1780{
1781 int i, j, k, m;
1782 // Working storage
1783 int size = (int)floor(n / 2.0) + 2;
1784 double *s = new double[size];
1785 double *t = new double[size];
1786
1787 // Initialize s and t to zero
1788 for (i = 0; i < size; i++)
1789 {
1790 s[i] = 0.0;
1791 t[i] = 0.0;
1792 }
1793
1794 t[1] = b[n + 1];
1795 for (m = 0; m <= n - 2; m++)
1796 {
1797 double u = 0.0;
1798 for (k = (int)floor((m + 1) / 2.0); k >= 0; k--)
1799 {
1800 int l = m - k;
1801 u = u + (a[k + n + 1] - a[l]) * t[k + 1] + b[k + n + 1] * s[k] -
1802 b[l] * s[k + 1];
1803 s[k + 1] = u;
1804 }
1805
1806 // Swap the contents of s and t
1807 double *hold = s;
1808 s = t;
1809 t = hold;
1810 }
1811
1812 for (j = (int)floor(n / 2.0); j >= 0; j--)
1813 {
1814 s[j + 1] = s[j];
1815 }
1816
1817 for (m = n - 1; m <= 2 * n - 3; m++)
1818 {
1819 double u = 0;
1820 for (k = m + 1 - n; k <= floor((m - 1) / 2.0); k++)
1821 {
1822 int l = m - k;
1823 j = n - 1 - l;
1824 u = u - (a[k + n + 1] - a[l]) * t[j + 1] - b[k + n + 1] * s[j + 1] +
1825 b[l] * s[j + 2];
1826 s[j + 1] = u;
1827 }
1828
1829 if (m % 2 == 0)
1830 {
1831 k = m / 2;
1832 a[k + n + 1] =
1833 a[k] + (s[j + 1] - b[k + n + 1] * s[j + 2]) / t[j + 2];
1834 }
1835 else
1836 {
1837 k = (m + 1) / 2;
1838 b[k + n + 1] = s[j + 1] / s[j + 2];
1839 }
1840
1841 // Swap the contents of s and t
1842 double *hold = s;
1843 s = t;
1844 t = hold;
1845 }
1846
1847 a[2 * n] = a[n - 1] - b[2 * n] * s[1] / t[1];
1848}

Referenced by zwgk(), zwlk(), and zwrk().

◆ laginterp()

double Polylib::laginterp ( double  z,
int  j,
const double *  zj,
int  np 
)

Definition at line 87 of file Polylib.cpp.

88{
89 double temp = 1.0;
90 for (int i = 0; i < np; i++)
91 {
92 if (j != i)
93 {
94 temp *= optdiff(z, zj[i]) / (zj[j] - zj[i]);
95 }
96 }
97 return temp;
98}
double optdiff(double xl, double xr)
The following function is used to circumvent/reduce "Subtractive Cancellation" The expression 1/dz is...
Definition: Polylib.cpp:57

References optdiff(), and Nektar::UnitTests::z().

Referenced by Nektar::LibUtilities::GaussPoints::CalculateInterpMatrix(), Nektar::LibUtilities::PolyEPoints::CalculateInterpMatrix(), hgj(), hglj(), hgrjm(), hgrjp(), and Nektar::LibUtilities::PolyEPoints::v_CalculateWeights().

◆ laginterpderiv()

double Polylib::laginterpderiv ( double  z,
int  k,
const double *  zj,
int  np 
)

Definition at line 100 of file Polylib.cpp.

101{
102 double y = 0.0;
103 for (int j = 0; j < np; ++j)
104 {
105 if (j != k)
106 {
107 double tmp = 1.0;
108 for (int i = 0; i < np; ++i)
109 {
110 if (i != k)
111 {
112 if (i != j)
113 {
114 tmp *= (z - zj[i]);
115 }
116 tmp /= (zj[k] - zj[i]);
117 }
118 }
119 y += tmp;
120 }
121 }
122 return y;
123}

References Nektar::UnitTests::z().

Referenced by Nektar::LibUtilities::GaussPoints::v_CalculateDerivMatrix(), and Nektar::LibUtilities::PolyEPoints::v_CalculateDerivMatrix().

◆ optdiff()

double Polylib::optdiff ( double  xl,
double  xr 
)

The following function is used to circumvent/reduce "Subtractive Cancellation" The expression 1/dz is replaced by optinvsub(.,.) Added on 26 April 2017.

Definition at line 57 of file Polylib.cpp.

58{
59 double m_xln, m_xrn;
60 int m_expn;
61 int m_digits = static_cast<int>(fabs(floor(log10(DBL_EPSILON))) - 1);
62
63 if (fabs(xl - xr) < 1.e-4)
64 {
65
66 m_expn = static_cast<int>(floor(log10(fabs(xl - xr))));
67 m_xln = xl * powl(10.0L, -m_expn) -
68 floor(xl * powl(10.0L,
69 -m_expn)); // substract the digits overlap part
70 m_xrn =
71 xr * powl(10.0L, -m_expn) -
72 floor(xl *
73 powl(10.0L,
74 -m_expn)); // substract the common digits overlap part
75 m_xln =
76 round(m_xln * powl(10.0L, m_digits + m_expn)); // git rid of rubbish
77 m_xrn = round(m_xrn * powl(10.0L, m_digits + m_expn));
78
79 return powl(10.0L, -m_digits) * (m_xln - m_xrn);
80 }
81 else
82 {
83 return (xl - xr);
84 }
85}

Referenced by laginterp().

◆ polycoeffs()

void Polylib::polycoeffs ( double *  c,
const double *  z,
const int  i,
const int  np 
)

Compute the coefficients of Lagrange interpolation polynomials.

Definition at line 1128 of file Polylib.cpp.

1129{
1130 int j, k, m;
1131
1132 // Compute denominator
1133 double d = 1.0;
1134 for (j = 0; j < np; j++)
1135 {
1136 if (i != j)
1137 {
1138 d *= z[i] - z[j];
1139 }
1140 c[j] = 0.0;
1141 }
1142
1143 // Compute coefficient
1144 c[0] = 1.0;
1145 m = 0;
1146 for (j = 0; j < np; j++)
1147 {
1148 if (i != j)
1149 {
1150 m += 1;
1151 c[m] = c[m - 1];
1152 for (k = m - 1; k > 0; k--)
1153 {
1154 c[k] *= -1.0 * z[j];
1155 c[k] += c[k - 1];
1156 }
1157 c[0] *= -1.0 * z[j];
1158 }
1159 }
1160 for (j = 0; j < np; j++)
1161 {
1162 c[j] /= d;
1163 }
1164}
std::vector< double > d(NPUPPER *NPUPPER)

References Nektar::UnitTests::d(), and Nektar::UnitTests::z().

Referenced by Qg().

◆ Qg()

void Polylib::Qg ( double *  Q,
const double *  z,
const int  np 
)

Compute the Integration Matrix.

Definition at line 605 of file Polylib.cpp.

606{
607
608 if (np <= 0)
609 {
610 Q[0] = 0.0;
611 }
612 else
613 {
614 int i, j, k;
615 double *pd;
616
617 pd = (double *)malloc(np * sizeof(double));
618
619 for (i = 0; i < np; i++)
620 {
621 polycoeffs(pd, z, i, np);
622 for (j = 0; j < np; j++)
623 {
624 Q[j * np + i] = 0.0;
625 for (k = 0; k < np; k++)
626 {
627 Q[j * np + i] += pd[k] / (k + 1) * pow(z[j], k + 1);
628 }
629 }
630 }
631 free(pd);
632 }
633 return;
634}
void polycoeffs(double *c, const double *z, const int i, const int np)
Compute the coefficients of Lagrange interpolation polynomials.
Definition: Polylib.cpp:1128

References polycoeffs(), and Nektar::UnitTests::z().

Referenced by Nektar::UnitTests::BOOST_AUTO_TEST_CASE(), and Nektar::LibUtilities::TimeIntegrationSchemeSDC::v_InitializeScheme().

◆ RecCoeff()

static void Polylib::RecCoeff ( const int  n,
double *  a,
double *  b,
const double  alpha,
const double  beta 
)
static

The routine finds the recurrence coefficients a and b of the orthogonal polynomials.

Definition at line 1607 of file Polylib.cpp.

1609{
1610
1611 int i;
1612 double apb, apbi, a2b2;
1613
1614 if (!n)
1615 return;
1616
1617 // generate normalised terms
1618 apb = alpha + beta;
1619 apbi = 2.0 + apb;
1620
1621 b[0] = pow(2.0, apb + 1.0) * gammaF(alpha + 1.0) * gammaF(beta + 1.0) /
1622 gammaF(apbi); // MuZero
1623 a[0] = (beta - alpha) / apbi;
1624 b[1] = (4.0 * (1.0 + alpha) * (1.0 + beta) / ((apbi + 1.0) * apbi * apbi));
1625
1626 a2b2 = beta * beta - alpha * alpha;
1627
1628 for (i = 1; i < n - 1; i++)
1629 {
1630 apbi = 2.0 * (i + 1) + apb;
1631 a[i] = a2b2 / ((apbi - 2.0) * apbi);
1632 b[i + 1] = (4.0 * (i + 1) * (i + 1 + alpha) * (i + 1 + beta) *
1633 (i + 1 + apb) / ((apbi * apbi - 1) * apbi * apbi));
1634 }
1635
1636 apbi = 2.0 * n + apb;
1637 a[n - 1] = a2b2 / ((apbi - 2.0) * apbi);
1638}

References Nektar::LibUtilities::beta, and gammaF().

Referenced by JacZeros(), zwgk(), zwlk(), and zwrk().

◆ TriQL()

static void Polylib::TriQL ( const int  n,
double *  d,
double *  e,
double **  z 
)
static

QL algorithm for symmetric tridiagonal matrix.

This subroutine is a translation of an algol procedure, num. math. 12, 377-383(1968) by martin and wilkinson, as modified in num. math. 15, 450(1970) by dubrulle. Handbook for auto. comp., vol.ii-linear algebra, 241-248(1971). This is a modified version from numerical recipes.

This subroutine finds the eigenvalues and first components of the eigenvectors of a symmetric tridiagonal matrix by the implicit QL method.

on input:

  • n is the order of the matrix;
  • d contains the diagonal elements of the input matrix;
  • e contains the subdiagonal elements of the input matrix in its first n-2 positions.
    • z is the n by n identity matrix

on output:

  • d contains the eigenvalues in ascending order.
  • e contains the weight values - modifications of the first component of normalised eigenvectors

Definition at line 1666 of file Polylib.cpp.

1667{
1668 int m, l, iter, i, k;
1669 double s, r, p, g, f, dd, c, b;
1670
1671 double MuZero = e[0];
1672
1673 // Renumber the elements of e
1674 for (i = 0; i < n - 1; i++)
1675 {
1676 e[i] = sqrt(e[i + 1]);
1677 }
1678 e[n - 1] = 0.0;
1679
1680 for (l = 0; l < n; l++)
1681 {
1682 iter = 0;
1683 do
1684 {
1685 for (m = l; m < n - 1; m++)
1686 {
1687 dd = fabs(d[m]) + fabs(d[m + 1]);
1688 if (fabs(e[m]) + dd == dd)
1689 break;
1690 }
1691 if (m != l)
1692 {
1693 if (iter++ == STOP)
1694 {
1695 fprintf(stderr, "triQL: Too many iterations in TQLI");
1696 exit(1);
1697 }
1698 g = (d[l + 1] - d[l]) / (2.0 * e[l]);
1699 r = sqrt((g * g) + 1.0);
1700 g = d[m] - d[l] + e[l] / (g + sign(r, g));
1701 s = c = 1.0;
1702 p = 0.0;
1703 for (i = m - 1; i >= l; i--)
1704 {
1705 f = s * e[i];
1706 b = c * e[i];
1707 if (fabs(f) >= fabs(g))
1708 {
1709 c = g / f;
1710 r = sqrt((c * c) + 1.0);
1711 e[i + 1] = f * r;
1712 c *= (s = 1.0 / r);
1713 }
1714 else
1715 {
1716 s = f / g;
1717 r = sqrt((s * s) + 1.0);
1718 e[i + 1] = g * r;
1719 s *= (c = 1.0 / r);
1720 }
1721 g = d[i + 1] - p;
1722 r = (d[i] - g) * s + 2.0 * c * b;
1723 p = s * r;
1724 d[i + 1] = g + p;
1725 g = c * r - b;
1726
1727 // Calculate the eigenvectors
1728 for (k = 0; k < n; k++)
1729 {
1730 f = z[k][i + 1];
1731 z[k][i + 1] = s * z[k][i] + c * f;
1732 z[k][i] = c * z[k][i] - s * f;
1733 }
1734 }
1735 d[l] = d[l] - p;
1736 e[l] = g;
1737 e[m] = 0.0;
1738 }
1739 } while (m != l);
1740 }
1741
1742 // order eigenvalues
1743 // Since we only need the first component of the eigenvectors
1744 // to calcualte the weight, we only swap the first components
1745 for (i = 0; i < n - 1; ++i)
1746 {
1747 k = i;
1748 p = d[i];
1749 for (l = i + 1; l < n; ++l)
1750 if (d[l] < p)
1751 {
1752 k = l;
1753 p = d[l];
1754 }
1755 d[k] = d[i];
1756 d[i] = p;
1757
1758 double temp = z[0][k];
1759 z[0][k] = z[0][i];
1760 z[0][i] = temp;
1761 }
1762
1763 // Calculate the weights
1764 for (i = 0; i < n; i++)
1765 {
1766 e[i] = MuZero * z[0][i] * z[0][i];
1767 }
1768}
#define sign(a, b)
return the sign(b)*a
Definition: Polylib.cpp:49

References Nektar::UnitTests::d(), CellMLToNektar.cellml_metadata::p, sign, tinysimd::sqrt(), STOP, and Nektar::UnitTests::z().

Referenced by JacZeros(), zwgk(), zwlk(), and zwrk().

◆ zwgj()

void Polylib::zwgj ( double *  z,
double *  w,
const int  np,
const double  alpha,
const double  beta 
)

Gauss-Jacobi zeros and weights.

  • Generate np Gauss Jacobi zeros, z, and weights,w, associated with the Jacobi polynomial \( P^{\alpha,\beta}_{np}(z) \),
  • Exact for polynomials of order 2np-1 or less

Definition at line 154 of file Polylib.cpp.

156{
157 int i;
158 double fac, one = 1.0, two = 2.0, apb = alpha + beta;
159
160 jacobz(np, z, alpha, beta);
161 jacobd(np, z, w, np, alpha, beta);
162
163 fac = pow(two, apb + one) * gammaFracGammaF(np + 1, alpha, np + 1, 0.0) *
164 gammaFracGammaF(np + 1, beta, np + 1, apb);
165
166 for (i = 0; i < np; ++i)
167 w[i] = fac / (w[i] * w[i] * (one - z[i] * z[i]));
168
169 return;
170}
#define jacobz(n, z, alpha, beta)
zero determination using Newton iteration with polynomial deflation
Definition: Polylib.cpp:130
std::vector< double > w(NPUPPER)

References Nektar::LibUtilities::beta, gammaFracGammaF(), jacobd(), jacobz, Nektar::UnitTests::w(), and Nektar::UnitTests::z().

Referenced by Nektar::UnitTests::BOOST_AUTO_TEST_CASE(), and Nektar::LibUtilities::GaussPoints::v_CalculatePoints().

◆ zwgk()

void Polylib::zwgk ( double *  z,
double *  w,
const int  npt,
const double  alpha,
const double  beta 
)

Gauss-Kronrod-Jacobi zeros and weights.

  • Generate npt=2*np+1 Gauss-Kronrod Jacobi zeros, z, and weights,w, associated with the Jacobi polynomial \( P^{\alpha,\beta}_{np}(z) \),
  • Exact for polynomials of order 3np+1 or less

Definition at line 311 of file Polylib.cpp.

313{
314
315 int np = (npt - 1) / 2;
316
317 int i, j;
318
319 // number of kronrod points associated with the np gauss rule
320 int kpoints = 2 * np + 1;
321
322 // Define the number of required recurrence coefficents
323 int ncoeffs = (int)floor(3.0 * (np + 1) / 2);
324
325 // Define arrays for the recurrence coefficients
326 // We will use these arrays for the Kronrod results too, hence the
327 // reason for the size of the arrays
328 double *a = new double[kpoints];
329 double *b = new double[kpoints];
330
331 // Initialize a and b to zero
332 for (i = 0; i < kpoints; i++)
333 {
334 a[i] = 0.0;
335 b[i] = 0.0;
336 }
337
338 // Call the routine to calculate the recurrence coefficients
339 RecCoeff(ncoeffs, a, b, alpha, beta);
340
341 // Call the routine to caluclate the jacobi-Kronrod matrix
342 JKMatrix(np, a, b);
343
344 // Set up the identity matrix
345 double **zmatrix = new double *[kpoints];
346 for (i = 0; i < kpoints; i++)
347 {
348 zmatrix[i] = new double[kpoints];
349 for (j = 0; j < kpoints; j++)
350 {
351 zmatrix[i][j] = 0.0;
352 }
353 }
354 for (i = 0; i < kpoints; i++)
355 {
356 zmatrix[i][i] = 1.0;
357 }
358
359 // Calculte the points and weights
360 TriQL(kpoints, a, b, zmatrix);
361
362 for (i = 0; i < kpoints; i++)
363 {
364 z[i] = a[i];
365 w[i] = b[i];
366 }
367 delete[] a;
368 delete[] b;
369 for (i = 0; i < kpoints; i++)
370 {
371 delete[] zmatrix[i];
372 }
373 delete[] zmatrix;
374}
void JKMatrix(int, double *, double *)
Calcualtes the Jacobi-kronrod matrix by determining the a and coefficients.
Definition: Polylib.cpp:1779

References Nektar::LibUtilities::beta, JKMatrix(), RecCoeff(), TriQL(), Nektar::UnitTests::w(), and Nektar::UnitTests::z().

Referenced by Nektar::LibUtilities::GaussPoints::v_CalculatePoints().

◆ zwglj()

void Polylib::zwglj ( double *  z,
double *  w,
const int  np,
const double  alpha,
const double  beta 
)

Gauss-Lobatto-Jacobi zeros and weights with end point at z=-1,1.

  • Generate np Gauss-Lobatto-Jacobi points, z, and weights, w, associated with polynomial \( (1-z)(1+z) P^{\alpha+1,\beta+1}_{np-2}(z) \)
  • Exact for polynomials of order 2np-3 or less

Definition at line 262 of file Polylib.cpp.

264{
265
266 if (np == 1)
267 {
268 z[0] = 0.0;
269 w[0] = 2.0;
270 }
271 else if (np == 2)
272 {
273 z[0] = -1.0;
274 z[1] = 1.0;
275
276 w[0] = 1.0;
277 w[1] = 1.0;
278 }
279 else
280 {
281 int i;
282 double fac, one = 1.0, apb = alpha + beta, two = 2.0;
283
284 z[0] = -one;
285 z[np - 1] = one;
286 jacobz(np - 2, z + 1, alpha + one, beta + one);
287 jacobfd(np, z, w, NULL, np - 1, alpha, beta);
288
289 fac = pow(two, apb + 1) * gammaFracGammaF(np, alpha, np, 0.0) *
290 gammaFracGammaF(np, beta, np + 1, apb);
291 fac /= (np - 1);
292
293 for (i = 0; i < np; ++i)
294 w[i] = fac / (w[i] * w[i]);
295 w[0] *= (beta + one);
296 w[np - 1] *= (alpha + one);
297 }
298
299 return;
300}

References Nektar::LibUtilities::beta, gammaFracGammaF(), jacobfd(), jacobz, Nektar::UnitTests::w(), and Nektar::UnitTests::z().

Referenced by Nektar::UnitTests::BOOST_AUTO_TEST_CASE(), and Nektar::LibUtilities::GaussPoints::v_CalculatePoints().

◆ zwgrjm()

void Polylib::zwgrjm ( double *  z,
double *  w,
const int  np,
const double  alpha,
const double  beta 
)

Gauss-Radau-Jacobi zeros and weights with end point at z=-1.

  • Generate np Gauss-Radau-Jacobi zeros, z, and weights,w, associated with the polynomial \((1+z) P^{\alpha,\beta+1}_{np-1}(z) \).
  • Exact for polynomials of order 2np-2 or less

Definition at line 182 of file Polylib.cpp.

184{
185
186 if (np == 1)
187 {
188 z[0] = 0.0;
189 w[0] = 2.0;
190 }
191 else
192 {
193 int i;
194 double fac, one = 1.0, two = 2.0, apb = alpha + beta;
195
196 z[0] = -one;
197 jacobz(np - 1, z + 1, alpha, beta + 1);
198 jacobfd(np, z, w, NULL, np - 1, alpha, beta);
199
200 fac = pow(two, apb) * gammaFracGammaF(np, alpha, np, 0.0) *
201 gammaFracGammaF(np, beta, np + 1, apb);
202 fac /= (beta + np);
203
204 for (i = 0; i < np; ++i)
205 w[i] = fac * (1 - z[i]) / (w[i] * w[i]);
206 w[0] *= (beta + one);
207 }
208
209 return;
210}

References Nektar::LibUtilities::beta, gammaFracGammaF(), jacobfd(), jacobz, Nektar::UnitTests::w(), and Nektar::UnitTests::z().

Referenced by Nektar::UnitTests::BOOST_AUTO_TEST_CASE(), and Nektar::LibUtilities::GaussPoints::v_CalculatePoints().

◆ zwgrjp()

void Polylib::zwgrjp ( double *  z,
double *  w,
const int  np,
const double  alpha,
const double  beta 
)

Gauss-Radau-Jacobi zeros and weights with end point at z=1.

  • Generate np Gauss-Radau-Jacobi zeros, z, and weights,w, associated with the polynomial \((1-z) P^{\alpha+1,\beta}_{np-1}(z) \).
  • Exact for polynomials of order 2np-2 or less

Definition at line 223 of file Polylib.cpp.

225{
226
227 if (np == 1)
228 {
229 z[0] = 0.0;
230 w[0] = 2.0;
231 }
232 else
233 {
234 int i;
235 double fac, one = 1.0, two = 2.0, apb = alpha + beta;
236
237 jacobz(np - 1, z, alpha + 1, beta);
238 z[np - 1] = one;
239 jacobfd(np, z, w, NULL, np - 1, alpha, beta);
240
241 fac = pow(two, apb) * gammaFracGammaF(np, alpha, np, 0.0) *
242 gammaFracGammaF(np, beta, np + 1, apb);
243 fac /= (alpha + np);
244
245 for (i = 0; i < np; ++i)
246 w[i] = fac * (1 + z[i]) / (w[i] * w[i]);
247 w[np - 1] *= (alpha + one);
248 }
249
250 return;
251}

References Nektar::LibUtilities::beta, gammaFracGammaF(), jacobfd(), jacobz, Nektar::UnitTests::w(), and Nektar::UnitTests::z().

Referenced by Nektar::UnitTests::BOOST_AUTO_TEST_CASE(), and Nektar::LibUtilities::GaussPoints::v_CalculatePoints().

◆ zwlk()

void Polylib::zwlk ( double *  z,
double *  w,
const int  npt,
const double  alpha,
const double  beta 
)

Gauss-Lobatto-Kronrod-Jacobi zeros and weights.

  • Generate npt=2*np-1 Lobatto-Kronrod Jacobi zeros, z, and weights,w, associated with the Jacobi polynomial \( P^{\alpha,\beta}_{np}(z) \),

Definition at line 489 of file Polylib.cpp.

491{
492
493 int np = (npt + 1) / 2;
494
495 if (np < 4)
496 {
497 fprintf(stderr, "too few points in formula\n");
498 return;
499 }
500
501 double endl = -1;
502 double endr = 1;
503 int i, j;
504
505 // number of kronrod points associated with the np gauss rule
506 int kpoints = 2 * np - 1;
507
508 // Define the number of required recurrence coefficents
509 int ncoeffs = (int)ceil(3.0 * np / 2) - 1;
510
511 // Define arrays for the recurrence coefficients
512 double *a = new double[ncoeffs + 1];
513 double *b = new double[ncoeffs + 1];
514
515 // Initialize a and b to zero
516 for (i = 0; i < ncoeffs + 1; i++)
517 {
518 a[i] = 0.0;
519 b[i] = 0.0;
520 }
521
522 // Call the routine to calculate the recurrence coefficients
523 RecCoeff(ncoeffs, a, b, alpha, beta);
524
525 double *a0 = new double[ncoeffs];
526 double *b0 = new double[ncoeffs];
527
528 chri1(ncoeffs, a, b, a0, b0, endl);
529
530 double *a1 = new double[ncoeffs - 1];
531 double *b1 = new double[ncoeffs - 1];
532
533 chri1(ncoeffs - 1, a0, b0, a1, b1, endr);
534
535 double s = b1[0] / fabs(b1[0]);
536 b1[0] = s * b1[0];
537
538 // Finding the 2*np-1 gauss-kronrod points
539 double *z1 = new double[2 * np - 3];
540 double *w1 = new double[2 * np - 3];
541 for (i = 0; i < ncoeffs; i++)
542 {
543 z1[i] = a1[i];
544 w1[i] = b1[i];
545 }
546 JKMatrix(np - 2, z1, w1);
547 // Set up the identity matrix
548 double **zmatrix = new double *[2 * np - 3];
549 for (i = 0; i < 2 * np - 3; i++)
550 {
551 zmatrix[i] = new double[2 * np - 3];
552 for (j = 0; j < 2 * np - 3; j++)
553 {
554 zmatrix[i][j] = 0.0;
555 }
556 }
557 for (i = 0; i < 2 * np - 3; i++)
558 {
559 zmatrix[i][i] = 1.0;
560 }
561
562 // Calculate the points and weights
563 TriQL(2 * np - 3, z1, w1, zmatrix);
564
565 double sumW1 = 0.0;
566 double sumW1Z1 = 0.0;
567 for (i = 0; i < 2 * np - 3; i++)
568 {
569 w1[i] = s * w1[i] / (z1[i] - endl) / (z1[i] - endr);
570 sumW1 += w1[i];
571 sumW1Z1 += z1[i] * w1[i];
572 }
573
574 double c0 = b[0] - sumW1;
575 double c1 = a[0] * b[0] - sumW1Z1;
576
577 z[0] = endl;
578 z[2 * np - 2] = endr;
579 w[0] = (c0 * endr - c1) / (endr - endl);
580 w[2 * np - 2] = (c1 - c0 * endl) / (endr - endl);
581
582 for (i = 1; i < kpoints - 1; i++)
583 {
584 z[i] = z1[i - 1];
585 w[i] = w1[i - 1];
586 }
587 delete[] a;
588 delete[] b;
589 delete[] a0;
590 delete[] b0;
591 delete[] a1;
592 delete[] b1;
593 delete[] z1;
594 delete[] w1;
595 for (i = 0; i < 2 * np - 3; i++)
596 {
597 delete[] zmatrix[i];
598 }
599 delete[] zmatrix;
600}
void chri1(int, double *, double *, double *, double *, double)
Given a weight function through the first n+1 coefficients a and b of its orthogonal polynomials thi...
Definition: Polylib.cpp:1860

References Nektar::LibUtilities::beta, chri1(), JKMatrix(), RecCoeff(), TriQL(), Nektar::UnitTests::w(), and Nektar::UnitTests::z().

Referenced by Nektar::LibUtilities::GaussPoints::v_CalculatePoints().

◆ zwrk()

void Polylib::zwrk ( double *  z,
double *  w,
const int  npt,
const double  alpha,
const double  beta 
)

Gauss-Radau-Kronrod-Jacobi zeros and weights.

  • Generate npt=2*np Radau-Kronrod Jacobi zeros, z, and weights,w, associated with the Jacobi polynomial \( P^{\alpha,\beta}_{np}(z) \),

Definition at line 383 of file Polylib.cpp.

385{
386
387 int np = npt / 2;
388
389 if (np < 2)
390 {
391 fprintf(stderr, "too few points in formula\n");
392 return;
393 }
394
395 double end0 = -1;
396
397 int i, j;
398
399 // number of kronrod points associated with the np gauss rule
400 int kpoints = 2 * np;
401
402 // Define the number of required recurrence coefficents
403 int ncoeffs = (int)ceil(3.0 * np / 2);
404
405 // Define arrays for the recurrence coefficients
406 double *a = new double[ncoeffs + 1];
407 double *b = new double[ncoeffs + 1];
408
409 // Initialize a and b to zero
410 for (i = 0; i < ncoeffs + 1; i++)
411 {
412 a[i] = 0.0;
413 b[i] = 0.0;
414 }
415
416 // Call the routine to calculate the recurrence coefficients
417 RecCoeff(ncoeffs, a, b, alpha, beta);
418
419 double *a0 = new double[ncoeffs];
420 double *b0 = new double[ncoeffs];
421
422 chri1(ncoeffs, a, b, a0, b0, end0);
423
424 double s = b0[0] / fabs(b0[0]);
425 b0[0] = s * b0[0];
426
427 // Finding the 2*np-1 gauss-kronrod points
428 double *z1 = new double[2 * np - 1];
429 double *w1 = new double[2 * np - 1];
430 for (i = 0; i < ncoeffs; i++)
431 {
432 z1[i] = a0[i];
433 w1[i] = b0[i];
434 }
435 JKMatrix(np - 1, z1, w1);
436 // Set up the identity matrix
437 double **zmatrix = new double *[2 * np - 1];
438 for (i = 0; i < 2 * np - 1; i++)
439 {
440 zmatrix[i] = new double[2 * np - 1];
441 for (j = 0; j < 2 * np - 1; j++)
442 {
443 zmatrix[i][j] = 0.0;
444 }
445 }
446 for (i = 0; i < 2 * np - 1; i++)
447 {
448 zmatrix[i][i] = 1.0;
449 }
450
451 // Calculate the points and weights
452 TriQL(2 * np - 1, z1, w1, zmatrix);
453
454 double sumW1 = 0.0;
455 for (i = 0; i < 2 * np - 1; i++)
456 {
457 w1[i] = s * w1[i] / (z1[i] - end0);
458 sumW1 += w1[i];
459 }
460
461 z[0] = end0;
462 w[0] = b[0] - sumW1;
463 for (i = 1; i < kpoints; i++)
464 {
465 z[i] = z1[i - 1];
466 w[i] = w1[i - 1];
467 }
468
469 delete[] a;
470 delete[] b;
471 delete[] a0;
472 delete[] b0;
473 delete[] z1;
474 delete[] w1;
475 for (i = 0; i < 2 * np - 1; i++)
476 {
477 delete[] zmatrix[i];
478 }
479 delete[] zmatrix;
480}

References Nektar::LibUtilities::beta, chri1(), JKMatrix(), RecCoeff(), TriQL(), Nektar::UnitTests::w(), and Nektar::UnitTests::z().

Referenced by Nektar::LibUtilities::GaussPoints::v_CalculatePoints().