diff --git a/.gitignore b/.gitignore
index b8d17d6fee23b736f9f4580745be7a890344ddf4..a23b9d5dcc5a5c85a926b8211cd41d8d0bfc5a84 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,3 @@
-misc/gegenbauer/*.txt
-misc/gegenbauer/gegenbauer_rule
 outputs
 pars/*/
 */**/*.so*
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index accda4ad2232ed783b81ebd233930d23d4fc10f3..5f2b05a7cafbfa4ee2e28b81e59afb3fd99f4bfe 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -5,8 +5,6 @@ image: julia:1.7
 before_script:
   # workaround for https://github.com/JuliaDocs/Documenter.jl/issues/686
   - apt-get -qq update; apt-get -y install git
-  # required to build gegenbauer rule
-  - apt-get -y install g++
   - julia --project=@. -e "import Pkg; Pkg.instantiate()"
 
 unittests:
diff --git a/misc/gegenbauer/README b/misc/gegenbauer/README
deleted file mode 100644
index 23efc1db62ef59d6eefb474fcd6f92e95d5be14b..0000000000000000000000000000000000000000
--- a/misc/gegenbauer/README
+++ /dev/null
@@ -1,3 +0,0 @@
-# Gauss-Gegenbauer Rule
-
-Source: https://people.sc.fsu.edu/~jburkardt/m_src/gegenbauer_rule/gegenbauer_rule.html
diff --git a/misc/gegenbauer/gegenbauer_rule.cpp b/misc/gegenbauer/gegenbauer_rule.cpp
deleted file mode 100644
index 9b0cfdbb47c32cc314a4f3323bcb709a537b9666..0000000000000000000000000000000000000000
--- a/misc/gegenbauer/gegenbauer_rule.cpp
+++ /dev/null
@@ -1,1500 +0,0 @@
-# include <cmath>
-# include <cstdlib>
-# include <cstring>
-# include <ctime>
-# include <fstream>
-# include <iomanip>
-# include <iostream>
-
-using namespace std;
-
-int main ( int argc, char *argv[] );
-void cdgqf ( int nt, int kind, double alpha, double beta, double t[], 
-  double wts[] );
-void cgqf ( int nt, int kind, double alpha, double beta, double a, double b, 
-  double t[], double wts[] );
-double class_matrix ( int kind, int m, double alpha, double beta, double aj[], 
-  double bj[] );
-void imtqlx ( int n, double d[], double e[], double z[] );
-void parchk ( int kind, int m, double alpha, double beta );
-double r8_epsilon ( );
-double r8_sign ( double x );
-void r8mat_write ( string output_filename, int m, int n, double table[] );
-void rule_write ( int order, string filename, double x[], double w[], 
-  double r[] );
-void scqf ( int nt, double t[], int mlt[], double wts[], int nwts, int ndx[], 
-  double swts[], double st[], int kind, double alpha, double beta, double a, 
-  double b );
-void sgqf ( int nt, double aj[], double bj[], double zemu, double t[], 
-  double wts[] );
-void timestamp ( );
-
-//****************************************************************************80
-
-int main ( int argc, char *argv[] )
-
-//****************************************************************************80
-//
-//  Purpose:
-//
-//    MAIN is the main program for GEGENBAUER_RULE.
-//
-//  Discussion:
-//
-//    This program computes a standard Gauss-Gegenbauer quadrature rule
-//    and writes it to a file.
-//
-//    The user specifies:
-//    * the ORDER (number of points) in the rule
-//    * the ALPHA parameter,
-//    * A, the left endpoint.
-//    * B, the right endpoint.
-//    * FILENAME, the root name of the output files.
-//
-//  Licensing:
-//
-//    This code is distributed under the GNU LGPL license. 
-//
-//  Modified:
-//
-//    28 February 2010
-//
-//  Author:
-//
-//    John Burkardt
-//
-{
-  double a;
-  double alpha;
-  double b;
-  double beta;
-  string filename;
-  int kind;
-  int order;
-  double *r;
-  double *w;
-  double *x;
-
-  cout << "\n";
-  timestamp ( );
-  cout << "\n";
-  cout << "GEGENBAUER_RULE\n";
-  cout << "  C++ version\n";
-  cout << "\n";
-  cout << "  Compute a Gauss-Gegenbauer quadrature rule for approximating\n";
-  cout << "    Integral ( A <= x <= B ) ((x-A)(B-X))^ALPHA f(x) dx\n";
-  cout << "  of order ORDER.\n";
-  cout << "\n";
-  cout << "  The user specifies ORDER, ALPHA, A, B, and FILENAME.\n";
-  cout << "\n";
-  cout << "  ORDER is the number of points:\n";
-  cout << "  ALPHA is the exponent:\n";
-  cout << "  A is the left endpoint:\n";
-  cout << "  B is the right endpoint:\n";
-  cout << "  FILENAME is used to generate 3 files:\n";
-  cout << "    filename_w.txt - the weight file\n";
-  cout << "    filename_x.txt - the abscissa file.\n";
-  cout << "    filename_r.txt - the region file.\n";
-//
-//  Initialize parameters;
-//
-  beta = 0.0;
-//
-//  Get ORDER.
-//
-  if ( 1 < argc )
-  {
-    order = atoi ( argv[1] );
-  }
-  else
-  {
-    cout << "\n";
-    cout << "  Enter the value of ORDER (1 or greater)\n";
-    cin >> order;
-  }
-//
-//  Get ALPHA.
-//
-  if ( 2 < argc )
-  {
-    alpha = atof ( argv[2] );
-  }
-  else
-  {
-    cout << "\n";
-    cout << "  ALPHA is the exponent of ((x-A)(B-X)) in the integral:\n";
-    cout << "  Note that -1.0 < ALPHA is required.\n";
-    cout << "  Enter the value of ALPHA:\n";
-    cin >> alpha;
-  }
-//
-//  Get A.
-//
-  if ( 3 < argc )
-  {
-    a = atof ( argv[3] );
-  }
-  else
-  {
-    cout << "\n";
-    cout << "  Enter the left endpoint A:\n";
-    cin >> a;
-  }
-//
-//  Get B.
-//
-  if ( 4 < argc )
-  {
-    b = atof ( argv[4] );
-  }
-  else
-  {
-    cout << "\n";
-    cout << "  Enter the right endpoint B:\n";
-    cin >> b;
-  }
-//
-//  Get FILENAME.
-//
-  if ( 5 < argc )
-  {
-    filename = argv[5];
-  }
-  else
-  {
-    cout << "\n";
-    cout << "  Enter FILENAME, the \"root name\" of the quadrature files).\n";
-    cin >> filename;
-  }
-//
-//  Input summary.
-//
-  cout << "\n";
-  cout << "  ORDER = " << order << "\n";
-  cout << "  ALPHA = " << alpha << "\n";
-  cout << "  A = " << a << "\n";
-  cout << "  B = " << b << "\n";
-  cout << "  FILENAME = \"" << filename << "\".\n";
-//
-//  Construct the rule.
-//
-  w = new double[order];
-  x = new double[order];
-  
-  kind = 3;
-  cgqf ( order, kind, alpha, beta, a, b, x, w );
-//
-//  Write the rule.
-//
-  r = new double[2];
-  r[0] = a;
-  r[1] = b;
-
-  rule_write ( order, filename, x, w, r );
-//
-//  Free memory.
-//
-  delete [] r;
-  delete [] w;
-  delete [] x;
-//
-//  Terminate.
-//
-  cout << "\n";
-  cout << "GEGENBAUER_RULE:\n";
-  cout << "  Normal end of execution.\n";
-
-  cout << "\n";
-  timestamp ( );
-
-  return 0;
-}
-//****************************************************************************80
-
-void cdgqf ( int nt, int kind, double alpha, double beta, double t[], 
-  double wts[] )
-
-//****************************************************************************80
-//
-//  Purpose:
-//
-//    CDGQF computes a Gauss quadrature formula with default A, B and simple knots.
-//
-//  Discussion:
-//
-//    This routine computes all the knots and weights of a Gauss quadrature
-//    formula with a classical weight function with default values for A and B,
-//    and only simple knots.
-//
-//    There are no moments checks and no printing is done.
-//
-//    Use routine EIQFS to evaluate a quadrature computed by CGQFS.
-//
-//  Licensing:
-//
-//    This code is distributed under the GNU LGPL license. 
-//
-//  Modified:
-//
-//    08 January 2010
-//
-//  Author:
-//
-//    Original FORTRAN77 version by Sylvan Elhay, Jaroslav Kautsky.
-//    C++ version by John Burkardt.
-//
-//  Reference:
-//
-//    Sylvan Elhay, Jaroslav Kautsky,
-//    Algorithm 655: IQPACK, FORTRAN Subroutines for the Weights of 
-//    Interpolatory Quadrature,
-//    ACM Transactions on Mathematical Software,
-//    Volume 13, Number 4, December 1987, pages 399-415.
-//
-//  Parameters:
-//
-//    Input, int NT, the number of knots.
-//
-//    Input, int KIND, the rule.
-//    1, Legendre,             (a,b)       1.0
-//    2, Chebyshev,            (a,b)       ((b-x)*(x-a))^(-0.5)
-//    3, Gegenbauer,           (a,b)       ((b-x)*(x-a))^alpha
-//    4, Jacobi,               (a,b)       (b-x)^alpha*(x-a)^beta
-//    5, Generalized Laguerre, (a,inf)     (x-a)^alpha*exp(-b*(x-a))
-//    6, Generalized Hermite,  (-inf,inf)  |x-a|^alpha*exp(-b*(x-a)^2)
-//    7, Exponential,          (a,b)       |x-(a+b)/2.0|^alpha
-//    8, Rational,             (a,inf)     (x-a)^alpha*(x+b)^beta
-//
-//    Input, double ALPHA, the value of Alpha, if needed.
-//
-//    Input, double BETA, the value of Beta, if needed.
-//
-//    Output, double T[NT], the knots.
-//
-//    Output, double WTS[NT], the weights.
-//
-{
-  double *aj;
-  double *bj;
-  double zemu;
-
-  parchk ( kind, 2 * nt, alpha, beta );
-//
-//  Get the Jacobi matrix and zero-th moment.
-//
-  aj = new double[nt];
-  bj = new double[nt];
-
-  zemu = class_matrix ( kind, nt, alpha, beta, aj, bj );
-//
-//  Compute the knots and weights.
-//
-  sgqf ( nt, aj, bj, zemu, t, wts );
-
-  delete [] aj;
-  delete [] bj;
-
-  return;
-}
-//****************************************************************************80
-
-void cgqf ( int nt, int kind, double alpha, double beta, double a, double b, 
-  double t[], double wts[] )
-
-//****************************************************************************80
-//
-//  Purpose:
-//
-//    CGQF computes knots and weights of a Gauss quadrature formula.
-//
-//  Discussion:
-//
-//    The user may specify the interval (A,B).
-//
-//    Only simple knots are produced.
-//
-//    Use routine EIQFS to evaluate this quadrature formula.
-//
-//  Licensing:
-//
-//    This code is distributed under the GNU LGPL license. 
-//
-//  Modified:
-//
-//    16 February 2010
-//
-//  Author:
-//
-//    Original FORTRAN77 version by Sylvan Elhay, Jaroslav Kautsky.
-//    C++ version by John Burkardt.
-//
-//  Reference:
-//
-//    Sylvan Elhay, Jaroslav Kautsky,
-//    Algorithm 655: IQPACK, FORTRAN Subroutines for the Weights of 
-//    Interpolatory Quadrature,
-//    ACM Transactions on Mathematical Software,
-//    Volume 13, Number 4, December 1987, pages 399-415.
-//
-//  Parameters:
-//
-//    Input, int NT, the number of knots.
-//
-//    Input, int KIND, the rule.
-//    1, Legendre,             (a,b)       1.0
-//    2, Chebyshev Type 1,     (a,b)       ((b-x)*(x-a))^-0.5)
-//    3, Gegenbauer,           (a,b)       ((b-x)*(x-a))^alpha
-//    4, Jacobi,               (a,b)       (b-x)^alpha*(x-a)^beta
-//    5, Generalized Laguerre, (a,+oo)     (x-a)^alpha*exp(-b*(x-a))
-//    6, Generalized Hermite,  (-oo,+oo)   |x-a|^alpha*exp(-b*(x-a)^2)
-//    7, Exponential,          (a,b)       |x-(a+b)/2.0|^alpha
-//    8, Rational,             (a,+oo)     (x-a)^alpha*(x+b)^beta
-//    9, Chebyshev Type 2,     (a,b)       ((b-x)*(x-a))^(+0.5)
-//
-//    Input, double ALPHA, the value of Alpha, if needed.
-//
-//    Input, double BETA, the value of Beta, if needed.
-//
-//    Input, double A, B, the interval endpoints, or
-//    other parameters.
-//
-//    Output, double T[NT], the knots.
-//
-//    Output, double WTS[NT], the weights.
-//
-{
-  int i;
-  int *mlt;
-  int *ndx;
-//
-//  Compute the Gauss quadrature formula for default values of A and B.
-//
-  cdgqf ( nt, kind, alpha, beta, t, wts );
-//
-//  Prepare to scale the quadrature formula to other weight function with 
-//  valid A and B.
-//
-  mlt = new int[nt];
-  for ( i = 0; i < nt; i++ )
-  {
-    mlt[i] = 1;
-  }
-  ndx = new int[nt];
-  for ( i = 0; i < nt; i++ )
-  {
-    ndx[i] = i + 1;
-  }
-  scqf ( nt, t, mlt, wts, nt, ndx, wts, t, kind, alpha, beta, a, b );
-
-  delete [] mlt;
-  delete [] ndx;
-
-  return;
-}
-//****************************************************************************80
-
-double class_matrix ( int kind, int m, double alpha, double beta, double aj[], 
-  double bj[] )
-
-//****************************************************************************80
-//
-//  Purpose:
-//
-//    CLASS_MATRIX computes the Jacobi matrix for a quadrature rule.
-//
-//  Discussion:
-//
-//    This routine computes the diagonal AJ and sub-diagonal BJ
-//    elements of the order M tridiagonal symmetric Jacobi matrix
-//    associated with the polynomials orthogonal with respect to
-//    the weight function specified by KIND.
-//
-//    For weight functions 1-7, M elements are defined in BJ even
-//    though only M-1 are needed.  For weight function 8, BJ(M) is
-//    set to zero.
-//
-//    The zero-th moment of the weight function is returned in ZEMU.
-//
-//  Licensing:
-//
-//    This code is distributed under the GNU LGPL license. 
-//
-//  Modified:
-//
-//    08 January 2010
-//
-//  Author:
-//
-//    Original FORTRAN77 version by Sylvan Elhay, Jaroslav Kautsky.
-//    C++ version by John Burkardt.
-//
-//  Reference:
-//
-//    Sylvan Elhay, Jaroslav Kautsky,
-//    Algorithm 655: IQPACK, FORTRAN Subroutines for the Weights of 
-//    Interpolatory Quadrature,
-//    ACM Transactions on Mathematical Software,
-//    Volume 13, Number 4, December 1987, pages 399-415.
-//
-//  Parameters:
-//
-//    Input, int KIND, the rule.
-//    1, Legendre,             (a,b)       1.0
-//    2, Chebyshev,            (a,b)       ((b-x)*(x-a))^(-0.5)
-//    3, Gegenbauer,           (a,b)       ((b-x)*(x-a))^alpha
-//    4, Jacobi,               (a,b)       (b-x)^alpha*(x-a)^beta
-//    5, Generalized Laguerre, (a,inf)     (x-a)^alpha*exp(-b*(x-a))
-//    6, Generalized Hermite,  (-inf,inf)  |x-a|^alpha*exp(-b*(x-a)^2)
-//    7, Exponential,          (a,b)       |x-(a+b)/2.0|^alpha
-//    8, Rational,             (a,inf)     (x-a)^alpha*(x+b)^beta
-//
-//    Input, int M, the order of the Jacobi matrix.
-//
-//    Input, double ALPHA, the value of Alpha, if needed.
-//
-//    Input, double BETA, the value of Beta, if needed.
-//
-//    Output, double AJ[M], BJ[M], the diagonal and subdiagonal
-//    of the Jacobi matrix.
-//
-//    Output, double CLASS_MATRIX, the zero-th moment.
-//
-{
-  double a2b2;
-  double ab;
-  double aba;
-  double abi;
-  double abj;
-  double abti;
-  double apone;
-  int i;
-  double pi = 3.14159265358979323846264338327950;
-  double temp;
-  double temp2;
-  double zemu;
-
-  temp = r8_epsilon ( );
-
-  parchk ( kind, 2 * m - 1, alpha, beta );
-
-  temp2 = 0.5;
-
-  if ( 500.0 * temp < fabs ( pow ( tgamma ( temp2 ), 2 ) - pi ) )
-  {
-    cout << "\n";
-    cout << "CLASS_MATRIX - Fatal error!\n";
-    cout << "  Gamma function does not match machine parameters.\n";
-    exit ( 1 );
-  }
-
-  if ( kind == 1 )
-  {
-    ab = 0.0;
-
-    zemu = 2.0 / ( ab + 1.0 );
-
-    for ( i = 0; i < m; i++ )
-    {
-      aj[i] = 0.0;
-    }
-
-    for ( i = 1; i <= m; i++ )
-    {
-      abi = i + ab * ( i % 2 );
-      abj = 2 * i + ab;
-      bj[i-1] = sqrt ( abi * abi / ( abj * abj - 1.0 ) );
-    }
-  }
-  else if ( kind == 2 )
-  {
-    zemu = pi;
-
-    for ( i = 0; i < m; i++ )
-    {
-      aj[i] = 0.0;
-    }
-
-    bj[0] =  sqrt ( 0.5 );
-    for ( i = 1; i < m; i++ )
-    {
-      bj[i] = 0.5;
-    }
-  }
-  else if ( kind == 3 )
-  {
-    ab = alpha * 2.0;
-    zemu = pow ( 2.0, ab + 1.0 ) * pow ( tgamma ( alpha + 1.0 ), 2 )
-      / tgamma ( ab + 2.0 );
-
-    for ( i = 0; i < m; i++ )
-    {
-      aj[i] = 0.0;
-    }
-
-    bj[0] = sqrt ( 1.0 / ( 2.0 * alpha + 3.0 ) );
-    for ( i = 2; i <= m; i++ )
-    {
-      bj[i-1] = sqrt ( i * ( i + ab ) / ( 4.0 * pow ( i + alpha, 2 ) - 1.0 ) );
-    }
-  }
-  else if ( kind == 4 )
-  {
-    ab = alpha + beta;
-    abi = 2.0 + ab;
-    zemu = pow ( 2.0, ab + 1.0 ) * tgamma ( alpha + 1.0 ) 
-      * tgamma ( beta + 1.0 ) / tgamma ( abi );
-    aj[0] = ( beta - alpha ) / abi;
-    bj[0] = sqrt ( 4.0 * ( 1.0 + alpha ) * ( 1.0 + beta ) 
-      / ( ( abi + 1.0 ) * abi * abi ) );
-    a2b2 = beta * beta - alpha * alpha;
-
-    for ( i = 2; i <= m; i++ )
-    {
-      abi = 2.0 * i + ab;
-      aj[i-1] = a2b2 / ( ( abi - 2.0 ) * abi );
-      abi = abi * abi;
-      bj[i-1] = sqrt ( 4.0 * i * ( i + alpha ) * ( i + beta ) * ( i + ab ) 
-        / ( ( abi - 1.0 ) * abi ) );
-    }
-  }
-  else if ( kind == 5 )
-  {
-    zemu = tgamma ( alpha + 1.0 );
-
-    for ( i = 1; i <= m; i++ )
-    {
-      aj[i-1] = 2.0 * i - 1.0 + alpha;
-      bj[i-1] = sqrt ( i * ( i + alpha ) );
-    }
-  }
-  else if ( kind == 6 )
-  {
-    zemu = tgamma ( ( alpha + 1.0 ) / 2.0 );
-
-    for ( i = 0; i < m; i++ )
-    {
-      aj[i] = 0.0;
-    }
-
-    for ( i = 1; i <= m; i++ )
-    {
-      bj[i-1] = sqrt ( ( i + alpha * ( i % 2 ) ) / 2.0 );
-    }
-  }
-  else if ( kind == 7 )
-  {
-    ab = alpha;
-    zemu = 2.0 / ( ab + 1.0 );
-
-    for ( i = 0; i < m; i++ )
-    {
-      aj[i] = 0.0;
-    }
-
-    for ( i = 1; i <= m; i++ )
-    {
-      abi = i + ab * ( i % 2 );
-      abj = 2 * i + ab;
-      bj[i-1] = sqrt ( abi * abi / ( abj * abj - 1.0 ) );
-    }
-  }
-  else if ( kind == 8 )
-  {
-    ab = alpha + beta;
-    zemu = tgamma ( alpha + 1.0 ) * tgamma ( - ( ab + 1.0 ) ) 
-      / tgamma ( - beta );
-    apone = alpha + 1.0;
-    aba = ab * apone;
-    aj[0] = - apone / ( ab + 2.0 );
-    bj[0] = - aj[0] * ( beta + 1.0 ) / ( ab + 2.0 ) / ( ab + 3.0 );
-    for ( i = 2; i <= m; i++ )
-    {
-      abti = ab + 2.0 * i;
-      aj[i-1] = aba + 2.0 * ( ab + i ) * ( i - 1 );
-      aj[i-1] = - aj[i-1] / abti / ( abti - 2.0 );
-    }
-
-    for ( i = 2; i <= m - 1; i++ )
-    {
-      abti = ab + 2.0 * i;
-      bj[i-1] = i * ( alpha + i ) / ( abti - 1.0 ) * ( beta + i ) 
-        / ( abti * abti ) * ( ab + i ) / ( abti + 1.0 );
-    }
-    bj[m-1] = 0.0;
-    for ( i = 0; i < m; i++ )
-    {
-      bj[i] =  sqrt ( bj[i] );
-    }
-  }
-
-  return zemu;
-}
-//****************************************************************************80
-
-void imtqlx ( int n, double d[], double e[], double z[] )
-
-//****************************************************************************80
-//
-//  Purpose:
-//
-//    IMTQLX diagonalizes a symmetric tridiagonal matrix.
-//
-//  Discussion:
-//
-//    This routine is a slightly modified version of the EISPACK routine to 
-//    perform the implicit QL algorithm on a symmetric tridiagonal matrix. 
-//
-//    The authors thank the authors of EISPACK for permission to use this
-//    routine. 
-//
-//    It has been modified to produce the product Q' * Z, where Z is an input 
-//    vector and Q is the orthogonal matrix diagonalizing the input matrix.  
-//    The changes consist (essentialy) of applying the orthogonal transformations
-//    directly to Z as they are generated.
-//
-//  Licensing:
-//
-//    This code is distributed under the GNU LGPL license. 
-//
-//  Modified:
-//
-//    08 January 2010
-//
-//  Author:
-//
-//    Original FORTRAN77 version by Sylvan Elhay, Jaroslav Kautsky.
-//    C++ version by John Burkardt.
-//
-//  Reference:
-//
-//    Sylvan Elhay, Jaroslav Kautsky,
-//    Algorithm 655: IQPACK, FORTRAN Subroutines for the Weights of 
-//    Interpolatory Quadrature,
-//    ACM Transactions on Mathematical Software,
-//    Volume 13, Number 4, December 1987, pages 399-415.
-//
-//    Roger Martin, James Wilkinson,
-//    The Implicit QL Algorithm,
-//    Numerische Mathematik,
-//    Volume 12, Number 5, December 1968, pages 377-383.
-//
-//  Parameters:
-//
-//    Input, int N, the order of the matrix.
-//
-//    Input/output, double D(N), the diagonal entries of the matrix.
-//    On output, the information in D has been overwritten.
-//
-//    Input/output, double E(N), the subdiagonal entries of the 
-//    matrix, in entries E(1) through E(N-1).  On output, the information in
-//    E has been overwritten.
-//
-//    Input/output, double Z(N).  On input, a vector.  On output,
-//    the value of Q' * Z, where Q is the matrix that diagonalizes the
-//    input symmetric tridiagonal matrix.
-//
-{
-  double b;
-  double c;
-  double f;
-  double g;
-  int i;
-  int ii;
-  int itn = 30;
-  int j;
-  int k;
-  int l;
-  int m;
-  int mml;
-  double p;
-  double prec;
-  double r;
-  double s;
-
-  prec = r8_epsilon ( );
-
-  if ( n == 1 )
-  {
-    return;
-  }
-
-  e[n-1] = 0.0;
-
-  for ( l = 1; l <= n; l++ )
-  {
-    j = 0;
-    for ( ; ; )
-    {
-      for ( m = l; m <= n; m++ )
-      {
-        if ( m == n )
-        {
-          break;
-        }
-
-        if ( fabs ( e[m-1] ) <= prec * ( fabs ( d[m-1] ) + fabs ( d[m] ) ) )
-        {
-          break;
-        }
-      }
-      p = d[l-1];
-      if ( m == l )
-      {
-        break;
-      }
-      if ( itn <= j )
-      {
-        cout << "\n";
-        cout << "IMTQLX - Fatal error!\n";
-        cout << "  Iteration limit exceeded\n";
-        exit ( 1 );
-      }
-      j = j + 1;
-      g = ( d[l] - p ) / ( 2.0 * e[l-1] );
-      r =  sqrt ( g * g + 1.0 );
-      g = d[m-1] - p + e[l-1] / ( g + fabs ( r ) * r8_sign ( g ) );
-      s = 1.0;
-      c = 1.0;
-      p = 0.0;
-      mml = m - l;
-
-      for ( ii = 1; ii <= mml; ii++ )
-      {
-        i = m - ii;
-        f = s * e[i-1];
-        b = c * e[i-1];
-
-        if ( fabs ( g ) <= fabs ( f ) )
-        {
-          c = g / f;
-          r =  sqrt ( c * c + 1.0 );
-          e[i] = f * r;
-          s = 1.0 / r;
-          c = c * s;
-        }
-        else
-        {
-          s = f / g;
-          r =  sqrt ( s * s + 1.0 );
-          e[i] = g * r;
-          c = 1.0 / r;
-          s = s * c;
-        }
-        g = d[i] - p;
-        r = ( d[i-1] - g ) * s + 2.0 * c * b;
-        p = s * r;
-        d[i] = g + p;
-        g = c * r - b;
-        f = z[i];
-        z[i] = s * z[i-1] + c * f;
-        z[i-1] = c * z[i-1] - s * f;
-      }
-      d[l-1] = d[l-1] - p;
-      e[l-1] = g;
-      e[m-1] = 0.0;
-    }
-  }
-//
-//  Sorting.
-//
-  for ( ii = 2; ii <= m; ii++ )
-  {
-    i = ii - 1;
-    k = i;
-    p = d[i-1];
-
-    for ( j = ii; j <= n; j++ )
-    {
-      if ( d[j-1] < p )
-      {
-         k = j;
-         p = d[j-1];
-      }
-    }
-
-    if ( k != i )
-    {
-      d[k-1] = d[i-1];
-      d[i-1] = p;
-      p = z[i-1];
-      z[i-1] = z[k-1];
-      z[k-1] = p;
-    }
-  }
-  return;
-}
-//****************************************************************************80
-
-void parchk ( int kind, int m, double alpha, double beta )
-
-//****************************************************************************80
-//
-//  Purpose:
-//
-//    PARCHK checks parameters ALPHA and BETA for classical weight functions. 
-//
-//  Licensing:
-//
-//    This code is distributed under the GNU LGPL license. 
-//
-//  Modified:
-//
-//    07 January 2010
-//
-//  Author:
-//
-//    Original FORTRAN77 version by Sylvan Elhay, Jaroslav Kautsky.
-//    C++ version by John Burkardt.
-//
-//  Reference:
-//
-//    Sylvan Elhay, Jaroslav Kautsky,
-//    Algorithm 655: IQPACK, FORTRAN Subroutines for the Weights of 
-//    Interpolatory Quadrature,
-//    ACM Transactions on Mathematical Software,
-//    Volume 13, Number 4, December 1987, pages 399-415.
-//
-//  Parameters:
-//
-//    Input, int KIND, the rule.
-//    1, Legendre,             (a,b)       1.0
-//    2, Chebyshev,            (a,b)       ((b-x)*(x-a))^(-0.5)
-//    3, Gegenbauer,           (a,b)       ((b-x)*(x-a))^alpha
-//    4, Jacobi,               (a,b)       (b-x)^alpha*(x-a)^beta
-//    5, Generalized Laguerre, (a,inf)     (x-a)^alpha*exp(-b*(x-a))
-//    6, Generalized Hermite,  (-inf,inf)  |x-a|^alpha*exp(-b*(x-a)^2)
-//    7, Exponential,          (a,b)       |x-(a+b)/2.0|^alpha
-//    8, Rational,             (a,inf)     (x-a)^alpha*(x+b)^beta
-//
-//    Input, int M, the order of the highest moment to
-//    be calculated.  This value is only needed when KIND = 8.
-//
-//    Input, double ALPHA, BETA, the parameters, if required
-//    by the value of KIND.
-//
-{
-  double tmp;
-
-  if ( kind <= 0 )
-  {
-    cout << "\n";
-    cout << "PARCHK - Fatal error!\n";
-    cout << "  KIND <= 0.\n";
-    exit ( 1 );
-  }
-//
-//  Check ALPHA for Gegenbauer, Jacobi, Laguerre, Hermite, Exponential.
-//
-  if ( 3 <= kind && alpha <= -1.0 )
-  {
-    cout << "\n";
-    cout << "PARCHK - Fatal error!\n";
-    cout << "  3 <= KIND and ALPHA <= -1.\n";
-    exit ( 1 );
-  }
-//
-//  Check BETA for Jacobi.
-//
-  if ( kind == 4 && beta <= -1.0 )
-  {
-    cout << "\n";
-    cout << "PARCHK - Fatal error!\n";
-    cout << "  KIND == 4 and BETA <= -1.0.\n";
-    exit ( 1 );
-  }
-//
-//  Check ALPHA and BETA for rational.
-//
-  if ( kind == 8 )
-  {
-    tmp = alpha + beta + m + 1.0;
-    if ( 0.0 <= tmp || tmp <= beta )
-    {
-      cout << "\n";
-      cout << "PARCHK - Fatal error!\n";
-      cout << "  KIND == 8 but condition on ALPHA and BETA fails.\n";
-      exit ( 1 );
-    }
-  }
-  return;
-}
-//****************************************************************************80
-
-double r8_epsilon ( )
-
-//****************************************************************************80
-//
-//  Purpose:
-//
-//    R8_EPSILON returns the R8 roundoff unit.
-//
-//  Discussion:
-//
-//    The roundoff unit is a number R which is a power of 2 with the
-//    property that, to the precision of the computer's arithmetic,
-//      1 < 1 + R
-//    but
-//      1 = ( 1 + R / 2 )
-//
-//  Licensing:
-//
-//    This code is distributed under the GNU LGPL license.
-//
-//  Modified:
-//
-//    01 September 2012
-//
-//  Author:
-//
-//    John Burkardt
-//
-//  Parameters:
-//
-//    Output, double R8_EPSILON, the R8 round-off unit.
-//
-{
-  const double value = 2.220446049250313E-016;
-
-  return value;
-}
-//****************************************************************************80
-
-double r8_sign ( double x )
-
-//****************************************************************************80
-//
-//  Purpose:
-//
-//    R8_SIGN returns the sign of an R8.
-//
-//  Licensing:
-//
-//    This code is distributed under the GNU LGPL license. 
-//
-//  Modified:
-//
-//    18 October 2004
-//
-//  Author:
-//
-//    John Burkardt
-//
-//  Parameters:
-//
-//    Input, double X, the number whose sign is desired.
-//
-//    Output, double R8_SIGN, the sign of X.
-//
-{
-  double value;
-
-  if ( x < 0.0 )
-  {
-    value = -1.0;
-  } 
-  else
-  {
-    value = 1.0;
-  }
-  return value;
-}
-//****************************************************************************80
-
-void r8mat_write ( string output_filename, int m, int n, double table[] )
-
-//****************************************************************************80
-//
-//  Purpose:
-//
-//    R8MAT_WRITE writes an R8MAT file with no header.
-//
-//  Licensing:
-//
-//    This code is distributed under the GNU LGPL license. 
-//
-//  Modified:
-//
-//    29 June 2009
-//
-//  Author:
-//
-//    John Burkardt
-//
-//  Parameters:
-//
-//    Input, string OUTPUT_FILENAME, the output filename.
-//
-//    Input, int M, the spatial dimension.
-//
-//    Input, int N, the number of points.
-//
-//    Input, double TABLE[M*N], the table data.
-//
-{
-  int i;
-  int j;
-  ofstream output;
-//
-//  Open the file.
-//
-  output.open ( output_filename.c_str ( ) );
-
-  if ( !output )
-  {
-    cerr << "\n";
-    cerr << "R8MAT_WRITE - Fatal error!\n";
-    cerr << "  Could not open the output file.\n";
-    return;
-  }
-//
-//  Write the data.
-//
-  for ( j = 0; j < n; j++ )
-  {
-    for ( i = 0; i < m; i++ )
-    {
-      output << "  " << setw(24) << setprecision(16) << table[i+j*m];
-    }
-    output << "\n";
-  }
-//
-//  Close the file.
-//
-  output.close ( );
-
-  return;
-}
-//****************************************************************************80
-
-void rule_write ( int order, string filename, double x[], double w[], 
-  double r[] )
-
-//****************************************************************************80
-//
-//  Purpose:
-//
-//    RULE_WRITE writes a quadrature rule to three files.
-//
-//  Licensing:
-//
-//    This code is distributed under the GNU LGPL license. 
-//
-//  Modified:
-//
-//    18 February 2010
-//
-//  Author:
-//
-//    John Burkardt
-//
-//  Parameters:
-//
-//    Input, int ORDER, the order of the rule.
-//
-//    Input, double A, the left endpoint.
-//
-//    Input, double B, the right endpoint.
-//
-//    Input, string FILENAME, specifies the output filenames.
-//    "filename_w.txt", "filename_x.txt", "filename_r.txt" 
-//    defining weights, abscissas, and region.
-// 
-{
-  string filename_r;
-  string filename_w;
-  string filename_x;
-
-  filename_w = filename + "_w.txt";
-  filename_x = filename + "_x.txt";
-  filename_r = filename + "_r.txt";
-
-  cout << "\n";
-  cout << "  Creating quadrature files.\n";
-  cout << "\n";
-  cout << "  Root file name is     \"" << filename   << "\".\n";
-  cout << "\n";
-  cout << "  Weight file will be   \"" << filename_w << "\".\n";
-  cout << "  Abscissa file will be \"" << filename_x << "\".\n";
-  cout << "  Region file will be   \"" << filename_r << "\".\n";
-            
-  r8mat_write ( filename_w, 1, order, w );
-  r8mat_write ( filename_x, 1, order, x );
-  r8mat_write ( filename_r, 1, 2,     r );
-  
-  return;
-}
-//****************************************************************************80
-
-void scqf ( int nt, double t[], int mlt[], double wts[], int nwts, int ndx[], 
-  double swts[], double st[], int kind, double alpha, double beta, double a, 
-  double b )
-
-//****************************************************************************80
-//
-//  Purpose:
-//
-//    SCQF scales a quadrature formula to a nonstandard interval.
-//
-//  Discussion:
-//
-//    The arrays WTS and SWTS may coincide.
-//
-//    The arrays T and ST may coincide.
-//
-//  Licensing:
-//
-//    This code is distributed under the GNU LGPL license. 
-//
-//  Modified:
-//
-//    16 February 2010
-//
-//  Author:
-//
-//    Original FORTRAN77 version by Sylvan Elhay, Jaroslav Kautsky.
-//    C++ version by John Burkardt.
-//
-//  Reference:
-//
-//    Sylvan Elhay, Jaroslav Kautsky,
-//    Algorithm 655: IQPACK, FORTRAN Subroutines for the Weights of 
-//    Interpolatory Quadrature,
-//    ACM Transactions on Mathematical Software,
-//    Volume 13, Number 4, December 1987, pages 399-415.
-//
-//  Parameters:
-//
-//    Input, int NT, the number of knots.
-//
-//    Input, double T[NT], the original knots.
-//
-//    Input, int MLT[NT], the multiplicity of the knots.
-//
-//    Input, double WTS[NWTS], the weights.
-//
-//    Input, int NWTS, the number of weights.
-//
-//    Input, int NDX[NT], used to index the array WTS.  
-//    For more details see the comments in CAWIQ.
-//
-//    Output, double SWTS[NWTS], the scaled weights.
-//
-//    Output, double ST[NT], the scaled knots.
-//
-//    Input, int KIND, the rule.
-//    1, Legendre,             (a,b)       1.0
-//    2, Chebyshev Type 1,     (a,b)       ((b-x)*(x-a))^(-0.5)
-//    3, Gegenbauer,           (a,b)       ((b-x)*(x-a))^alpha
-//    4, Jacobi,               (a,b)       (b-x)^alpha*(x-a)^beta
-//    5, Generalized Laguerre, (a,+oo)     (x-a)^alpha*exp(-b*(x-a))
-//    6, Generalized Hermite,  (-oo,+oo)   |x-a|^alpha*exp(-b*(x-a)^2)
-//    7, Exponential,          (a,b)       |x-(a+b)/2.0|^alpha
-//    8, Rational,             (a,+oo)     (x-a)^alpha*(x+b)^beta
-//    9, Chebyshev Type 2,     (a,b)       ((b-x)*(x-a))^(+0.5)
-//
-//    Input, double ALPHA, the value of Alpha, if needed.
-//
-//    Input, double BETA, the value of Beta, if needed.
-//
-//    Input, double A, B, the interval endpoints.
-//
-{
-  double al;
-  double be;
-  int i;
-  int k;
-  int l;
-  double p;
-  double shft;
-  double slp;
-  double temp;
-  double tmp;
-
-  temp = r8_epsilon ( );
-
-  parchk ( kind, 1, alpha, beta );
-
-  if ( kind == 1 )
-  {
-    al = 0.0;
-    be = 0.0;
-    if ( fabs ( b - a ) <= temp )
-    {
-      cout << "\n";
-      cout << "SCQF - Fatal error!\n";
-      cout << "  |B - A| too small.\n";
-      exit ( 1 );
-    }
-    shft = ( a + b ) / 2.0;
-    slp = ( b - a ) / 2.0;
-  }
-  else if ( kind == 2 )
-  {
-    al = -0.5;
-    be = -0.5;
-    if ( fabs ( b - a ) <= temp )
-    {
-      cout << "\n";
-      cout << "SCQF - Fatal error!\n";
-      cout << "  |B - A| too small.\n";
-      exit ( 1 );
-    }
-    shft = ( a + b ) / 2.0;
-    slp = ( b - a ) / 2.0;
-  }
-  else if ( kind == 3 )
-  {
-    al = alpha;
-    be = alpha;
-    if ( fabs ( b - a ) <= temp )
-    {
-      cout << "\n";
-      cout << "SCQF - Fatal error!\n";
-      cout << "  |B - A| too small.\n";
-      exit ( 1 );
-    }
-    shft = ( a + b ) / 2.0;
-    slp = ( b - a ) / 2.0;
-  }
-  else if ( kind == 4 )
-  {
-    al = alpha;
-    be = beta;
-
-    if ( fabs ( b - a ) <= temp )
-    {
-      cout << "\n";
-      cout << "SCQF - Fatal error!\n";
-      cout << "  |B - A| too small.\n";
-      exit ( 1 );
-    }
-    shft = ( a + b ) / 2.0;
-    slp = ( b - a ) / 2.0;
-  }
-  else if ( kind == 5 )
-  {
-    if ( b <= 0.0 )
-    {
-      cout << "\n";
-      cout << "SCQF - Fatal error!\n";
-      cout << "  B <= 0\n";
-      exit ( 1 );
-    }
-    shft = a;
-    slp = 1.0 / b;
-    al = alpha;
-    be = 0.0;
-  }
-  else if ( kind == 6 )
-  {
-    if ( b <= 0.0 )
-    {
-      cout << "\n";
-      cout << "SCQF - Fatal error!\n";
-      cout << "  B <= 0.\n";
-      exit ( 1 );
-    }
-    shft = a;
-    slp = 1.0 / sqrt ( b );
-    al = alpha;
-    be = 0.0;
-  }
-  else if ( kind == 7 )
-  {
-    al = alpha;
-    be = 0.0;
-    if ( fabs ( b - a ) <= temp )
-    {
-      cout << "\n";
-      cout << "SCQF - Fatal error!\n";
-      cout << "  |B - A| too small.\n";
-      exit ( 1 );
-    }
-    shft = ( a + b ) / 2.0;
-    slp = ( b - a ) / 2.0;
-  }
-  else if ( kind == 8 )
-  {
-    if ( a + b <= 0.0 )
-    {
-      cout << "\n";
-      cout << "SCQF - Fatal error!\n";
-      cout << "  A + B <= 0.\n";
-      exit ( 1 );
-    }
-    shft = a;
-    slp = a + b;
-    al = alpha;
-    be = beta;
-  }
-  else if ( kind == 9 )
-  {
-    al = 0.5;
-    be = 0.5;
-    if ( fabs ( b - a ) <= temp )
-    {
-      cout << "\n";
-      cout << "SCQF - Fatal error!\n";
-      cout << "  |B - A| too small.\n";
-      exit ( 1 );
-    }
-    shft = ( a + b ) / 2.0;
-    slp = ( b - a ) / 2.0;
-  }
-
-  p = pow ( slp, al + be + 1.0 );
-
-  for ( k = 0; k < nt; k++ )
-  {
-    st[k] = shft + slp * t[k];
-    l = abs ( ndx[k] );
-
-    if ( l != 0 )
-    {
-      tmp = p;
-      for ( i = l - 1; i <= l - 1 + mlt[k] - 1; i++ )
-      {
-        swts[i] = wts[i] * tmp;
-        tmp = tmp * slp;
-      }
-    }
-  }
-  return;
-}
-//****************************************************************************80
-
-void sgqf ( int nt, double aj[], double bj[], double zemu, double t[], 
-  double wts[] )
-
-//****************************************************************************80
-//
-//  Purpose:
-//
-//    SGQF computes knots and weights of a Gauss Quadrature formula.
-//
-//  Discussion:
-//
-//    This routine computes all the knots and weights of a Gauss quadrature
-//    formula with simple knots from the Jacobi matrix and the zero-th
-//    moment of the weight function, using the Golub-Welsch technique.
-//
-//  Licensing:
-//
-//    This code is distributed under the GNU LGPL license. 
-//
-//  Modified:
-//
-//    08 January 2010
-//
-//  Author:
-//
-//    Original FORTRAN77 version by Sylvan Elhay, Jaroslav Kautsky.
-//    C++ version by John Burkardt.
-//
-//  Reference:
-//
-//    Sylvan Elhay, Jaroslav Kautsky,
-//    Algorithm 655: IQPACK, FORTRAN Subroutines for the Weights of 
-//    Interpolatory Quadrature,
-//    ACM Transactions on Mathematical Software,
-//    Volume 13, Number 4, December 1987, pages 399-415.
-//
-//  Parameters:
-//
-//    Input, int NT, the number of knots.
-//
-//    Input, double AJ[NT], the diagonal of the Jacobi matrix.
-//
-//    Input/output, double BJ[NT], the subdiagonal of the Jacobi 
-//    matrix, in entries 1 through NT-1.  On output, BJ has been overwritten.
-//
-//    Input, double ZEMU, the zero-th moment of the weight function.
-//
-//    Output, double T[NT], the knots.
-//
-//    Output, double WTS[NT], the weights.
-//
-{
-  int i;
-//
-//  Exit if the zero-th moment is not positive.
-//
-  if ( zemu <= 0.0 )
-  {
-    cout << "\n";
-    cout << "SGQF - Fatal error!\n";
-    cout << "  ZEMU <= 0.\n";
-    exit ( 1 );
-  }
-//
-//  Set up vectors for IMTQLX.
-//
-  for ( i = 0; i < nt; i++ )
-  {
-    t[i] = aj[i];
-  }
-  wts[0] = sqrt ( zemu );
-  for ( i = 1; i < nt; i++ )
-  {
-    wts[i] = 0.0;
-  }
-//
-//  Diagonalize the Jacobi matrix.
-//
-  imtqlx ( nt, t, bj, wts );
-
-  for ( i = 0; i < nt; i++ )
-  {
-    wts[i] = wts[i] * wts[i];
-  }
-
-  return;
-}
-//****************************************************************************80
-
-void timestamp ( )
-
-//****************************************************************************80
-//
-//  Purpose:
-//
-//    TIMESTAMP prints the current YMDHMS date as a time stamp.
-//
-//  Example:
-//
-//    31 May 2001 09:45:54 AM
-//
-//  Licensing:
-//
-//    This code is distributed under the GNU LGPL license. 
-//
-//  Modified:
-//
-//    08 July 2009
-//
-//  Author:
-//
-//    John Burkardt
-//
-//  Parameters:
-//
-//    None
-//
-{
-# define TIME_SIZE 40
-
-  static char time_buffer[TIME_SIZE];
-  const struct std::tm *tm_ptr;
-  std::time_t now;
-
-  now = std::time ( NULL );
-  tm_ptr = std::localtime ( &now );
-
-  std::strftime ( time_buffer, TIME_SIZE, "%d %B %Y %I:%M:%S %p", tm_ptr );
-
-  std::cout << time_buffer << "\n";
-
-  return;
-# undef TIME_SIZE
-}
-
diff --git a/src/ScalarEq/setup.jl b/src/ScalarEq/setup.jl
index 6c5bff892b86acd2acdf3799059fc2a542a2fdc6..83a083f822723ba880969c045e514ee30278d446 100644
--- a/src/ScalarEq/setup.jl
+++ b/src/ScalarEq/setup.jl
@@ -24,6 +24,9 @@ function Project(env::Environment, prms)
   !isnothing(av_rsolver) && register_variables!(cache, av_rsolver, dont_register=true)
   display(cache)
 
+  # setup initial data
+  initialdata!(env, P, prms["ScalarEq"])
+
   # setup boundary conditions
   bdryconds = make_BoundaryConditions(env, equation, rsolver, prms["ScalarEq"])
   ldg_bdryconds, av_bdryconds = if hrsc isa AbstractArtificialViscosity
@@ -39,9 +42,6 @@ function Project(env::Environment, prms)
   # somewhere. For periodic BCs we don't need extra storage at all.
   # But what other types of boundary conditions will be needed in the future?
 
-  # setup initial data
-  initialdata!(env, P, prms["ScalarEq"])
-
   # setup callbacks
   projectcb = make_callback(env, P, bdryconds)
 
diff --git a/src/dg1d.jl b/src/dg1d.jl
index 5e26b83cc0a01254d7ed10be2a4ef204d4691415..ebe6cea6e3565e4af11fc986ef88cea3de13ec57 100644
--- a/src/dg1d.jl
+++ b/src/dg1d.jl
@@ -56,7 +56,6 @@ export Bisection, NewtonSolver, find_root
 include("rootfinders.jl")
 include("fd.jl")
 include("lagrange.jl")
-include("gb.jl")
 include("glgl.jl")
 include("lgl.jl")
 include("evolve.jl")
diff --git a/src/gb.jl b/src/gb.jl
deleted file mode 100644
index 50a771cef3146bdd50322c393012fd4d17503f3b..0000000000000000000000000000000000000000
--- a/src/gb.jl
+++ /dev/null
@@ -1,93 +0,0 @@
-module GB
-
-
-function fname_rule(n_pts)
-  thisdir = dirname(@__FILE__)
-  fname = "$thisdir/../misc/gegenbauer/rule_$n_pts"
-  fname = normpath(fname)
-  return fname
-end # function
-
-
-
-"""
-Compute nodes and weights for Gegenbauer rule using external C++ program.
-The C++ program dg1d/misc/gegenbauer/gegenbauer_rule should be build with the commands
-```
-  \$ cd dg1d/misc/gegenbauer
-  \$ g++ gegenbauer_rule.cpp -o gegenbauer_rule
-```
-
-n_pts ... = order + 1
-"""
-function generate_nodes_weights(n_pts)
-
-  # only interested in standard interval x ϵ [-1,1] with weight (1-t^2)^2
-  α = 2.0
-  A = -1.0
-  B = 1.0
-
-  thisdir = dirname(@__FILE__)
-  exe = "$thisdir/../misc/gegenbauer/gegenbauer_rule"
-  exe = normpath(exe)
-
-  if ! isfile(exe)
-    src = normpath("$thisdir/../misc/gegenbauer/gegenbauer_rule.cpp")
-    run(`g++ $src -o $exe`)
-  end
-
-  fname = fname_rule(n_pts)
-
-  pipe = pipeline(`$exe $n_pts $α $A $B $fname`, stdout=devnull, stderr=devnull)
-  run(pipe)
-end # function
-
-
-
-"""
-Read Gauss-Gegenbauer quadrature nodes and weights from file located at
-evm/gegenbauer. If no file is found for requested number of points n_pts,
-we generate it by calling rule(n_pts).
-n_pts must be greater than 0.
-"""
-function rule(n_pts)
-
-  fname = fname_rule(n_pts)
-  fname_w = "$(fname)_w.txt"
-  fname_r = "$(fname)_r.txt"
-  fname_x = "$(fname)_x.txt"
-
-  rule_exists = isfile(fname_w) && isfile(fname_r) && isfile(fname_x)
-
-  if ! rule_exists 
-    generate_nodes_weights(n_pts)
-  end
-
-  x = zeros(n_pts)
-  w = zeros(n_pts)
-
-  file = open(fname_x, "r")
-  idx = 1
-  while !eof(file)
-    l = readline(file)
-    l = strip(l)
-    x[idx] = parse(Float64, l)
-    idx += 1
-  end
-  close(file)
-
-  file = open(fname_w, "r")
-  idx = 1
-  while !eof(file)
-    l = readline(file)
-    l = strip(l)
-    w[idx] = parse(Float64, l)
-    idx += 1
-  end
-  close(file)
-
-  return x, w
-end # function
-
-
-end # GB
diff --git a/src/glgl.jl b/src/glgl.jl
index 60ebfc894d1c0ac4aae5668c740bbac297e2e46f..c567a1e637f725f42e9e2eb12a1c035590877e91 100644
--- a/src/glgl.jl
+++ b/src/glgl.jl
@@ -2,11 +2,11 @@ module GLGL
 
 
 using LinearAlgebra, Jacobi
-import dg1d: GB, purge_zeros!, lagrange_poly
+import dg1d: purge_zeros!, lagrange_poly
 
 
 @doc """
-Computes quadrature nodes, weights and derivative weights 
+Computes quadrature nodes, weights and derivative weights
 for the Generalized-Gauss-Lobatto quadrature rule.
 n_pts ... number of quadrature nodes
 Return values
@@ -19,7 +19,10 @@ function rule(n_pts)
   N = n_pts - 2
   gb_x, gb_w = [], []
   if N > 0
-    gb_x, gb_w = GB.rule(N)
+    # Integration nodes and weights for Gauss-Gegenbauer quadrature
+    α = 2; β = 2
+    gb_x = zgj(N,    α, β)
+    gb_w = wgj(gb_x, α, β)
   end
 
   x = zeros(n_pts)