def gridtopatch(NM, index): M, N = NM, nmodesP S, WS = shifts(M), spec.chebweights(N) X, Y = spec.chebnodes(N), spec.chebnodes(N) CC = np.insert(np.cumsum(WS) - 1, 0, -1) PX = np.sort((X + S[index[0], index[1]][0])/M) PY = np.sort(-(Y + S[index[0], index[1]][1])/M) return PX, PY
def gridtopatch(self, PATCH, index): """ Gives the integration weights and the """ M, N = self.M, self.N S, WS = self.shifts(M), spec.chebweights(N) X, Y = spec.chebnodes(PATCH.N), spec.chebnodes(PATCH.N) CC = np.insert(np.cumsum(WS) - 1, 0, -1) self.PX = np.sort((X + S[index[0], index[1]][0])/M) self.PY = np.sort(-(Y + S[index[0], index[1]][1])/M) self.WX = np.sort((CC + S[index[0], index[1]][0])/M) self.WY = np.sort(-(CC + S[index[0], index[1]][1])/M) return self.WX, self.WY, self.PX, self.PY
def computeL2forpatch(NM): #-------------------------------------------------------------- # Starting to compute solution #-------------------------------------------------------------- if (1): # Two gaussians advecting computationaldomain = multipatch(npatches=1, nmodes=20, \ leftboundary = lambda x: np.exp(-(x**2.0)/0.1), \ rightboundary = lambda y: np.exp(-(y**2.0)/0.1), \ potential = None, nboundarymodes = NM) AF = lambda x, y: np.exp(-(x**2.0) / 0.1) + np.exp(-(y**2.0) / 0.1) else: # Two sine waves advecting computationaldomain = multipatch(npatches=1, nmodes=NM, \ leftboundary = lambda x: np.sin(np.pi*x), \ rightboundary = lambda y: np.sin(np.pi*y), \ potential = None, nboundarymodes = NM) AF = lambda x, y: -np.sin(np.pi * x) + -np.sin(np.pi * y) #-------------------------------------------------------------- # Call solver #-------------------------------------------------------------- domain = computationaldomain.globalsolve()[0, 0] #-------------------------------------------------------------- # Extract coefficents from the patch #-------------------------------------------------------------- CP = spec.vandermonde(computationaldomain.N, \ spec.chebnodes(computationaldomain.N)) VNDM = np.kron(CP, CP) CFS = np.linalg.solve(VNDM, np.ravel(domain)) COEFFS = np.reshape(CFS, (computationaldomain.N + 1, computationaldomain.N + 1)) #-------------------------------------------------------------- # Mow plot the solution at a different set of points #-------------------------------------------------------------- """ There could be two ways to do this - Pad the coefficent matrix with zeros and then evaluate the Vandermonde matrix - Compute the Vandermonde matrix in 2D for nmodes != npoints - Very confusing with Krons. Doing this explicitly. """ #-------------------------------------------------------------- # Points where you're evaluating the new solution #-------------------------------------------------------------- XNEW, YNEW = spec.chebnodes(computationaldomain.N*2 + 1), \ spec.chebnodes(computationaldomain.N*2 + 1) if (0): #-------------------------------------------------------------- # loop over all new points of the solution [SLOW!] [DEBUG?] #-------------------------------------------------------------- PSOL = np.zeros( (computationaldomain.N * 2 + 2, computationaldomain.N * 2 + 2)) for i, _x in enumerate(XNEW): # all points in x-dir for j, _y in enumerate(YNEW): # all points in y-dir SUM = 0 T = np.eye(100) for index, value in np.ndenumerate( COEFFS): # sum over all coefficents k = index[0] l = index[1] Tk_x = np.polynomial.chebyshev.chebval(_x, T[k]) Tl_y = np.polynomial.chebyshev.chebval(_y, T[l]) SUM = SUM + COEFFS[index] * Tk_x * Tl_y PSOL[i, j] = SUM else: #-------------------------------------------------------------- # Pad coefficent matrix with zeros #-------------------------------------------------------------- COEFFS_P = np.pad(COEFFS, \ (0, (computationaldomain.N*2 + 1) - computationaldomain.N), 'constant') CQP= spec.vandermonde(computationaldomain.N*2 + 1, \ spec.chebnodes(computationaldomain.N*2 + 1)) VNDM_P = np.kron(CQP, CQP) PSOLV = np.dot(VNDM_P, np.ravel(COEFFS_P)) PSOL = np.reshape( PSOLV, (computationaldomain.N * 2 + 2, computationaldomain.N * 2 + 2)) #-------------------------------------------------------------- # Now compute the analytic solution at the same points #-------------------------------------------------------------- ASOL = np.zeros( (computationaldomain.N * 2 + 2, computationaldomain.N * 2 + 2)) for i, _x in enumerate(XNEW): for j, _y in enumerate(YNEW): ASOL[i, j] = AF(_x, _y) #-------------------------------------------------------------- # Compute L2 norm error #-------------------------------------------------------------- AS = np.ravel(ASOL) PS = np.ravel(PSOL) GW = np.ravel(np.outer(spec.chebweights(computationaldomain.N*2 + 1), \ spec.chebweights(computationaldomain.N*2 + 1))) L2 = np.sqrt( np.abs(np.dot(GW, (PS - AS)**2.0) / np.abs(np.dot(GW, AS**2.0)))) #-------------------------------------------------------------- # Plot the solution if necessary #-------------------------------------------------------------- if (0): import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D fig = plt.figure() ax = fig.add_subplot(111, projection='3d') # xx, yy = np.meshgrid(spec.chebnodes(computationaldomain.N), \ # spec.chebnodes(computationaldomain.N)) # ax.plot_wireframe(xx, yy, domain, linewidth=0.8) XX, YY = np.meshgrid(spec.chebnodes(computationaldomain.N*2+1), \ spec.chebnodes(computationaldomain.N*2+1)) ax.plot_wireframe(XX, YY, PSOL, color='k', linewidth=0.8) ax.plot_wireframe(XX, YY, ASOL, color='g', linewidth=0.8) plt.show() return L2
def integrationweights(self): # returns a 2D diagonal matrix N = self.N return np.diag(np.ravel(np.outer(spec.chebweights(N), \ spec.chebweights(N))))
def computeL2forgrid(NM): #-------------------------------------------------------------- # Starting to compute solution #-------------------------------------------------------------- if(0): computationaldomain = multipatch(npatches=NM, nmodes=nmodesP, \ leftboundary = lambda x: np.exp(-(x**2.0)/0.1), \ rightboundary = lambda y: np.exp(-(y**2.0)/0.1), \ potential = None) AF = lambda x, y: np.exp(-(x**2.0)/0.1) + np.exp(-(y**2.0)/0.1) else: computationaldomain = multipatch(npatches=NM, nmodes=nmodesP, \ leftboundary = lambda x: np.sin(np.pi*x), \ rightboundary = lambda y: np.sin(np.pi*y), \ potential = None) AF = lambda x, y: np.sin(np.pi*x) + np.sin(np.pi*y) #-------------------------------------------------------------- # Call solver #-------------------------------------------------------------- grid = computationaldomain.globalsolve() #-------------------------------------------------------------- # Project the solution on each patch #-------------------------------------------------------------- for index_grid, val in np.ndenumerate(grid): domain = grid[index_grid] #-------------------------------------------------------------- # Extract coefficents from the patch #-------------------------------------------------------------- CP = spec.vandermonde(computationaldomain.N, \ spec.chebnodes(computationaldomain.N)) VNDM = np.kron(CP, CP) CFS = np.linalg.solve(VNDM, np.ravel(domain)) COEFFS = np.reshape(CFS, (computationaldomain.N+1, computationaldomain.N+1)) #-------------------------------------------------------------- # Points where you're evaluating the new solution #-------------------------------------------------------------- X, Y = spec.chebnodes(computationaldomain.N), spec.chebnodes(computationaldomain.N) XNEW, YNEW = gridtopatch(NM, index_grid) #-------------------------------------------------------------- # loop over all new points of the solution [SLOW!] [DEBUG] #-------------------------------------------------------------- PSOL = np.zeros((len(XNEW), len(YNEW))) for i, _x in enumerate(XNEW): # all points in x-dir for j, _y in enumerate(YNEW): # all points in y-dir SUM = 0 T = np.eye(100) for index, value in np.ndenumerate(COEFFS): # sum over all coefficents k = index[0] l = index[1] Tk_x = np.polynomial.chebyshev.chebval(_x, T[k]) Tl_y = np.polynomial.chebyshev.chebval(_y, T[l]) SUM = SUM + COEFFS[index]*Tk_x*Tl_y PSOL[i,j] = SUM #-------------------------------------------------------------- # Now compute the analytic solution at the same points #-------------------------------------------------------------- ASOL = np.zeros((len(XNEW), len(YNEW))) for i, _x in enumerate(XNEW): for j, _y in enumerate(YNEW): ASOL[i,j] = AF(_x,_y) if(1): import matplotlib.pyplot as plt # from mpl_toolkits.mplot3d import Axes3D # fig = plt.figure() # ax = fig.add_subplot(111, projection='3d') # XX, YY = np.meshgrid(spec.chebnodes(nmodesP), \ # spec.chebnodes(nmodesP)) # ax.plot_wireframe(XX, YY, PSOL, color='k', linewidth=0.8) # ax.plot_wireframe(XX, YY, ASOL, color='g', linewidth=0.8) plt.subplot(131) plt.contourf(X, Y, domain) plt.colorbar() plt.subplot(132) plt.contourf(XNEW, YNEW, PSOL) plt.colorbar() plt.subplot(133) plt.contourf(XNEW, YNEW, ASOL) plt.colorbar() plt.show() np.set_printoptions(precision=4) #-------------------------------------------------------------- # Compute L2 norm error #-------------------------------------------------------------- AS = np.ravel(ASOL) PS = np.ravel(PSOL) # print 50*"-" # print index_grid # print AS # print PS # print 50*"-" GW = np.ravel(np.outer(spec.chebweights(nmodesP), \ spec.chebweights(nmodesP))) L2 = np.sqrt(np.abs(np.dot(GW, (PS-AS)**2.0)/np.abs(np.dot(GW, AS**2.0)))) print "PATCH %r L2 = %r"%(index_grid, L2) return L2
def computeL2forpatch(NM): sinwave = 0 #-------------------------------------------------------------- # Starting to compute solution #-------------------------------------------------------------- if (sinwave): # Two gaussians advecting computationaldomain = multipatch(npatches=1, nmodes=20, \ leftboundary = lambda x: np.exp(-(x**2.0)/0.1), \ rightboundary = lambda y: np.exp(-(y**2.0)/0.1), \ potential = None, nboundarymodes = NM) AF = lambda x, y: np.exp(-(x**2.0) / 0.1) + np.exp(-(y**2.0) / 0.1) else: # Two sine waves advecting computationaldomain = multipatch(npatches=1, nmodes=NM, \ leftboundary = lambda x: np.sin(np.pi*x), \ rightboundary = lambda y: np.sin(np.pi*y), \ potential = None, nboundarymodes = NM) AF = lambda x, y: -np.sin(np.pi * x) + -np.sin(np.pi * y) #-------------------------------------------------------------- # Call solver #-------------------------------------------------------------- domain = computationaldomain.globalsolve()[0, 0] #-------------------------------------------------------------- # Extract coefficents from the patch #-------------------------------------------------------------- CP = spec.vandermonde(computationaldomain.N, \ spec.chebnodes(computationaldomain.N)) VNDM = np.kron(CP, CP) CFS = np.linalg.solve(VNDM, np.ravel(domain)) COEFFS = np.reshape(CFS, (computationaldomain.N + 1, computationaldomain.N + 1)) #-------------------------------------------------------------- # Points where you're evaluating the new solution #-------------------------------------------------------------- XNEW, YNEW = spec.chebnodes(computationaldomain.N*2 + 1), \ spec.chebnodes(computationaldomain.N*2 + 1) #-------------------------------------------------------------- # Pad coefficent matrix with zeros #-------------------------------------------------------------- COEFFS_P = np.pad(COEFFS, \ (0, (computationaldomain.N*2 + 1) - computationaldomain.N), 'constant') CQP= spec.vandermonde(computationaldomain.N*2 + 1, \ spec.chebnodes(computationaldomain.N*2 + 1)) VNDM_P = np.kron(CQP, CQP) PSOLV = np.dot(VNDM_P, np.ravel(COEFFS_P)) PSOL = np.reshape( PSOLV, (computationaldomain.N * 2 + 2, computationaldomain.N * 2 + 2)) #-------------------------------------------------------------- # Now compute the lower mode boundary solution solution #-------------------------------------------------------------- if (sinwave): # Two gaussians advecting computationaldomain = multipatch(npatches=1, nmodes=20, \ leftboundary = lambda x: np.exp(-(x**2.0)/0.1), \ rightboundary = lambda y: np.exp(-(y**2.0)/0.1), \ potential = None, nboundarymodes = NM+1) AF = lambda x, y: np.exp(-(x**2.0) / 0.1) + np.exp(-(y**2.0) / 0.1) else: # Two sine waves advecting computationaldomain = multipatch(npatches=1, nmodes=NM, \ leftboundary = lambda x: np.sin(np.pi*x), \ rightboundary = lambda y: np.sin(np.pi*y), \ potential = None, nboundarymodes = NM+1) AF = lambda x, y: -np.sin(np.pi * x) + -np.sin(np.pi * y) #-------------------------------------------------------------- # Call solver #-------------------------------------------------------------- domain = computationaldomain.globalsolve()[0, 0] #-------------------------------------------------------------- # Extract coefficents from the patch #-------------------------------------------------------------- CP = spec.vandermonde(computationaldomain.N, \ spec.chebnodes(computationaldomain.N)) VNDM = np.kron(CP, CP) CFS = np.linalg.solve(VNDM, np.ravel(domain)) COEFFS = np.reshape(CFS, (computationaldomain.N + 1, computationaldomain.N + 1)) #-------------------------------------------------------------- # Now, plot the solution at a different set of points #-------------------------------------------------------------- XNEW, YNEW = spec.chebnodes(computationaldomain.N*2 + 1), \ spec.chebnodes(computationaldomain.N*2 + 1) #-------------------------------------------------------------- # Pad coefficent matrix with zeros #-------------------------------------------------------------- COEFFS_P = np.pad(COEFFS, \ (0, (computationaldomain.N*2 + 1) - computationaldomain.N), 'constant') CQP= spec.vandermonde(computationaldomain.N*2 + 1, \ spec.chebnodes(computationaldomain.N*2 + 1)) VNDM_P = np.kron(CQP, CQP) PSOLV = np.dot(VNDM_P, np.ravel(COEFFS_P)) ASOL = np.reshape( PSOLV, (computationaldomain.N * 2 + 2, computationaldomain.N * 2 + 2)) #-------------------------------------------------------------- # Compute L2 norm error #-------------------------------------------------------------- AS = np.ravel(ASOL) PS = np.ravel(PSOL) GW = np.ravel(np.outer(spec.chebweights(computationaldomain.N*2 + 1), \ spec.chebweights(computationaldomain.N*2 + 1))) L2 = np.sqrt( np.abs(np.dot(GW, (PS - AS)**2.0) / np.abs(np.dot(GW, AS**2.0)))) return L2
from scalarwave_spectral import spec from scalarwave_patch import patch # test projection of 2D functions on grid np.set_printoptions(precision=4) x, y = spec.chebnodes(28), spec.chebnodes(28) xx, yy = np.meshgrid(x, y) zz = np.exp(-(xx)**2.0) + np.exp(-(yy)**2.0) f = lambda x, y: np.exp(-(x)**2.0/0.1) + np.exp(-(y)**2.0/0.1) print "- Computing analytic solution." # project the analytic function # extremeley restricted in the domain in which this works. FIX IT. zzP = spec.projectfunction2D(f, 28, spec.chebnodes(28)) print "- Finished projecting analytic solution." # Compute L2 norm error AS = np.ravel(zz) # renaming vars PS = np.ravel(zzP) GW = np.ravel(np.outer(spec.chebweights(28), spec.chebweights(28))) print "+ L2 error norm:", np.sqrt(np.abs(np.dot(GW, (PS-AS)**2.0)/np.abs(np.dot(GW, AS**2.0)))) if(0): import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D fig = plt.figure() ax = fig.add_subplot(111, projection='3d') ax.plot_wireframe(xx, yy, zz, linewidth=0.8) ax.plot_wireframe(xx, yy, zzP, color='k', linewidth=0.8) plt.show()