def lagrange(N, i, x): """ Function to calculate Lagrange polynomial for order N and polynomial i[0, N] at location x. """ from gll import gll [xi, weights] = gll(N) fac = 1 for j in range(-1, N): if j != i: fac = fac * ((x - xi[j + 1]) / (xi[i + 1] - xi[j + 1])) return fac
def lagrange1st(N): # Calculation of 1st derivatives of Lagrange polynomials # at GLL collocation points # out = legendre1st(N) # out is a matrix with columns -> GLL nodes # rows -> order from gll import gll from lagrange import lagrange from legendre import legendre import numpy as np out = np.zeros([N+1, N+1]) [xi, w] = gll(N) # initialize dij matrix (see Funaro 1993 or Diploma thesis Bernhard Schuberth) d = np.zeros([N+1, N+1]) for i in range (-1, N): for j in range (-1, N): if i != j: d[i+1,j+1] = legendre(N,xi[i+1])/legendre(N,xi[j+1])*1/(xi[i+1]-xi[j+1]) if i == -1: if j == -1: d[i+1,j+1] = float(-1)/float(4)*N*(N+1) if i == N-1: if j == N-1: d[i+1,j+1] = float(1)/float(4)*N*(N+1) # Calculate matrix with 1st derivatives of Lagrange polynomials for n in range (-1, N): for i in range (-1, N): sum=0 for j in range(-1, N): sum = sum + d[i+1,j+1]*lagrange(N,n,xi[j+1]) out[n+1,i+1] = sum return(out)
def lagrange(N, i, x): # Program to calculate Lagrange polynomial for order N # and polynomial i [0, N] at location x from gll import gll [xi, weights] = gll(N) fac = 1 for j in range(-1, N): if j != i: fac = fac * ((x - xi[j + 1]) / (xi[i + 1] - xi[j + 1])) x = fac return x
def lagrange1st(N): # Calculation of 1st derivatives of Lagrange polynomials # at GLL collocation points # out = legendre1st(N) # out is a matrix with columns -> GLL nodes # rows -> order from gll import gll from lagrange import lagrange from legendre import legendre import numpy as np out = np.zeros([N + 1, N + 1]) [xi, w] = gll(N) # initialize dij matrix (see Funaro 1993 or Diploma thesis Bernhard Schuberth) d = np.zeros([N + 1, N + 1]) for i in range(-1, N): for j in range(-1, N): if i != j: d[i + 1, j + 1] = legendre(N, xi[i + 1]) / legendre( N, xi[j + 1]) * 1 / (xi[i + 1] - xi[j + 1]) if i == -1: if j == -1: d[i + 1, j + 1] = float(-1) / float(4) * N * (N + 1) if i == N - 1: if j == N - 1: d[i + 1, j + 1] = float(1) / float(4) * N * (N + 1) # Calculate matrix with 1st derivatives of Lagrange polynomials for n in range(-1, N): for i in range(-1, N): sum = 0 for j in range(-1, N): sum = sum + d[i + 1, j + 1] * lagrange(N, n, xi[j + 1]) out[n + 1, i + 1] = sum return (out)
def lagrange(N,i,x): # Program to calculate Lagrange polynomial for order N # and polynomial i [0, N] at location x from gll import gll [xi, weights] = gll(N) fac=1 for j in range (-1,N): if j != i: fac=fac*((x-xi[j+1])/(xi[i+1]-xi[j+1])) x=fac return x
def lagrange1st(N): """ # Calculation of 1st derivatives of Lagrange polynomials # at GLL collocation points # out = legendre1st(N) # out is a matrix with columns -> GLL nodes # rows -> order """ out = np.zeros([N+1, N+1]) [xi, w] = gll(N) # initialize dij matrix (see Funaro 1993 or Diploma thesis Bernhard # Schuberth) d = np.zeros([N + 1, N + 1]) for i in range(-1, N): for j in range(-1, N): if i != j: d[i + 1, j + 1] = legendre(N, xi[i + 1]) / \ legendre(N, xi[j + 1]) * 1.0 / (xi[i + 1] - xi[j + 1]) if i == -1: if j == -1: d[i + 1, j + 1] = -1.0 / 4.0 * N * (N + 1) if i == N-1: if j == N-1: d[i + 1, j + 1] = 1.0 / 4.0 * N * (N + 1) # Calculate matrix with 1st derivatives of Lagrange polynomials for n in range(-1, N): for i in range(-1, N): sum = 0 for j in range(-1, N): sum = sum + d[i + 1, j + 1] * lagrange(N, n, xi[j + 1]) out[n + 1, i + 1] = sum return(out)
xmax = 10000. # Length of domain [m] vs = 2500. # S velocity [m/s] rho = 2000 # Density [kg/m^3] mu = rho * vs**2 # Shear modulus mu N = 3 # Order of Lagrange polynomials ne = 250 # Number of elements Tdom = .2 # Dominant period of Ricker source wavelet iplot = 20 # Plotting each iplot snapshot # variables for elemental matrices Me = np.zeros(N + 1, dtype=float) Ke = np.zeros((N + 1, N + 1), dtype=float) # ---------------------------------------------------------------- # Initialization of GLL points integration weights [xi, w] = gll(N) # xi, N+1 coordinates [-1 1] of GLL points # w Integration weights at GLL locations # Space domain le = xmax / ne # Length of elements # Vector with GLL points k = 0 xg = np.zeros((N * ne) + 1) xg[k] = 0 for i in range(1, ne + 1): for j in range(0, N): k = k + 1 xg[k] = (i - 1) * le + .5 * (xi[j + 1] + 1) * le # --------------------------------------------------------------- dxmin = min(np.diff(xg)) eps = 0.1 # Courant value
# + def lagrange2(N, i, x, xi): """ Function to calculate Lagrange polynomial for order N and polynomial i [0, N] at location x at given collacation points xi (not necessarily the GLL-points) """ fac = 1 for j in range(-1, N): if j != i: fac = fac * ((x - xi[j + 1]) / (xi[i + 1] - xi[j + 1])) return fac N = 4 x = np.linspace(-1, 1, 1000) xi, _ = gll(N) plt.figure(figsize=(8, 3)) for _i in range(N): plt.plot(x, lagrange2(N, _i, x, xi)) plt.ylim(-0.3, 1.1) plt.title("Lagrange Polynomials of order %i" % N) plt.show() # - # ##Exercises: # # ### 1. The GLL-points # * Use the `gll()` routine to determine the collocation points for a given order $N$ in the interval $[-1,1]$. # * Define an arbitrary function $f(x)$ and use the function `lagrange(N,i,x)` to get the $i$-th Lagrange polynomials of order N at the point x. # * Calculate the interpolating function to $f(x)$.
n = 1000 x = np.linspace(-1, 1, n) # MODIFY f and intf to test different functions! f = np.sin(x * np.pi) # Analytical value of the DEFINITE integral from -1 to 1 intf = 1.0 / np.pi * (-np.cos(1.0 * np.pi) + np.cos(-1.0 * np.pi)) # Choose order N = 4 # Uncomment for interactivity. # N =int(input('Give order of integration: ')) # Get integration points and weights from the gll routine xi, w = gll(N) # Initialize function at points xi fi = np.interp(xi, x, f) # Evaluate integral intfn = 0 for i in range(len(w)): intfn = intfn + w[i] * fi[i] # Calculate Lagrange Interpolant for plotting purposes. lp = np.zeros((N + 1, len(x))) for i in range(0, len(x)): for j in range(-1, N): lp[j + 1, i] = lagrange2(N, j, x[i], xi) s = np.zeros_like(x)