[cig-commits] [commit] master: py: Simplify GLJ derivative calculation. (99350f0)
cig_noreply at geodynamics.org
cig_noreply at geodynamics.org
Wed Jan 14 09:29:31 PST 2015
Repository : https://github.com/geodynamics/specfem1d
On branch : master
Link : https://github.com/geodynamics/specfem1d/compare/2ccfba13481e26296eebf034518cd31d2c727906...33b512de01491f2c70de206939855d95b22febf4
>---------------------------------------------------------------
commit 99350f0c91ebfe334d89ae640270437d3b2a40a0
Author: Elliott Sales de Andrade <esalesde at physics.utoronto.ca>
Date: Mon Jan 12 16:11:45 2015 -0500
py: Simplify GLJ derivative calculation.
Instead of interpolating a high-resolution Legendre polynomial, we can
just ask for the points we want directly. The loop with a bunch of
conditions is hard to read and probably inefficient, so just do the
indexing manually.
>---------------------------------------------------------------
99350f0c91ebfe334d89ae640270437d3b2a40a0
Python_version/gll.py | 71 +++++++++++++++++++++++++++------------------------
1 file changed, 38 insertions(+), 33 deletions(-)
diff --git a/Python_version/gll.py b/Python_version/gll.py
index 20fe8cc..06d141e 100644
--- a/Python_version/gll.py
+++ b/Python_version/gll.py
@@ -81,39 +81,44 @@ def lagrange_derivative(ksiGLL):
def glj_derivative(ksiGLJ):
"""Calculates the values of the derivative of the polynomials associated
to the Gauss-Lobatto-Jacobi quadrature at the GLJ points"""
- N=len(ksiGLJ)-1
- deriv=np.zeros((N+1,N+1),dtype='d')
- lenX=100000
- xi = np.linspace(-1,1,lenX)
- xi2=(xi[1:len(xi)]+xi[0:len(xi)-1])/2
- dxi=xi[1]-xi[0]
- P = np.polynomial.legendre.legval(xi, np.identity(8))
- Pb=np.zeros_like(P[N])
- Pb[1:]=(P[N][1:]+P[N+1][1:])/(1.+xi[1:])
- Pb[0]=round(Pb[1]) # =+-(N+1)
- PbInterp = interp1d(xi, Pb)
- for i in np.arange(N+1):
- for j in np.arange(N+1):
- if i == 0 and j == 0:
- deriv[i,j] = -N*(N+2.)/6.
- elif i == 0 and 0 < j < N:
- deriv[i,j] = 2*(-1)**N*PbInterp(ksiGLJ[j])/((1+ksiGLJ[j])*(N+1))
- elif i == 0 and j == N:
- deriv[i,j] = (-1)**N/(N+1)
- elif 0 < i < N and j == 0:
- deriv[i,j] = (-1)**(N+1)*(N+1)/(2*PbInterp(ksiGLJ[i])*(1+ksiGLJ[i]))
- elif 0 < i < N and 0 < j < N and i != j:
- deriv[i,j] = 1/(ksiGLJ[j]-ksiGLJ[i])*PbInterp(ksiGLJ[j])/PbInterp(ksiGLJ[i])
- elif 0 < i < N and i == j:
- deriv[i,j] = -1/(2*(1+ksiGLJ[i]))
- elif 0 < i < N and j == N:
- deriv[i,j] = 1/(1-ksiGLJ[i])*1/PbInterp(ksiGLJ[i])
- elif i == N and j == 0:
- deriv[i,j] = (-1)**(N+1)*(N+1)/4.
- elif i == N and 0 < j < N:
- deriv[i,j] = -1/(1-ksiGLJ[j])*PbInterp(ksiGLJ[j])
- elif i == N and j == N:
- deriv[i,j] = (N*(N+2)-1.)/4.
+ N = len(ksiGLJ) - 1
+ # Only need interior points. Exterior points need special treatment.
+ ksiGLJ = ksiGLJ[1:N]
+
+ coef = np.zeros(N + 2)
+ coef[N:] = 1.0
+ L = np.polynomial.legendre.Legendre(coef)
+ Ld = L.deriv()
+ glj_poly = Ld(ksiGLJ)
+
+ deriv = np.zeros((N + 1, N + 1))
+
+ # Top row
+ deriv[0, 0] = -N * (N + 2) / 6.0
+ deriv[0, 1:N] = 2 * (-1)**N * glj_poly / ((1 + ksiGLJ) * (N + 1))
+ deriv[0, N] = (-1)**N / (N + 1)
+
+ # Left column
+ deriv[1:N, 0] = (-1)**(N + 1) * (N + 1) / (2 * glj_poly * (1 + ksiGLJ))
+
+ # Middle block
+ for i in range(1, N):
+ # The index for ksiGLJ and glj_poly is shifted because we dropped the
+ # first element earlier.
+ deriv[i, i] = -1 / (2 * (1 + ksiGLJ[i - 1]))
+ deriv[i, i + 1:N] = (glj_poly[i:] / glj_poly[i - 1] /
+ (ksiGLJ[i:] - ksiGLJ[i - 1]))
+ deriv[i + 1:N, i] = (glj_poly[i - 1] / glj_poly[i:] /
+ (ksiGLJ[i - 1] - ksiGLJ[i:]))
+
+ # Right column
+ deriv[1:N, N] = 1 / (1 - ksiGLJ) / glj_poly
+
+ # Bottom row
+ deriv[N, 0] = (-1)**(N + 1) * (N + 1) / 4.0
+ deriv[N, 1:N] = -1 / (1 - ksiGLJ) * glj_poly
+ deriv[N, N] = (N * (N + 2) - 1) / 4.0
+
return deriv
More information about the CIG-COMMITS
mailing list