Pe = 10. # global Peclet numbers problem = 1 # problem to solve (set =1) FVSCHEME = ['cds-cds', 'uds-cds'] # finite volume schemes analyzed ## Initialize ERROR = np.zeros((len(N), len(FVSCHEME))) # max. trunc. error array ROC = np.zeros(len(FVSCHEME)) # rate of conv. array TL = np.zeros((len(N), len(FVSCHEME))) # tendency lines array ## Compute max. truncation errors of FV-solutions for all N, PE, FVSCHEME for i in range(0, len(N)): for j in range(0, len(FVSCHEME)): n = N[i] A, s = FVConvDiff2D.preprocess(n, L, Pe, problem, FVSCHEME[j]) # Coordinate arrays dx = L/n # cell size in x,y-direction xf = np.arange(0., L+dx, dx) # cell face coords along x,y-axis xc = np.arange(dx/2., L, dx) # cell center coordinates along x-axis Xc, _ = np.meshgrid(xc, xc) # 2D cell center x-coordinate array T = spsolve(A, s.reshape(1, n**2, order='F')) # direct solution # Error T_error = T-Texact(Pe, np.reshape(Xc, (1, n**2), order='F')) ERROR[i, j] = np.max(np.abs(T_error)) # infinity norm ## Compute rates of convergence TL = np.zeros((len(N), len(FVSCHEME)))
Nasymp = 1e8 # large number of cells for asymp. Oasymp = 2 - 1e-6 # asymp. value for omega_opt(Nasymp) ## Initialize OMopt = np.zeros((len(PE), len(N))) # optimal omega array P = np.zeros((len(PE), 2)) # fitting poly. coeff. for OMopt Ni = np.round(np.logspace(1, 4, 100)) # cell-number vector for tendency curves TC = np.zeros((len(PE), len(Ni))) # tendency curves for OMopt-results ## Compute optimal omega_SOR for coarse grids for i in range(0, len(PE)): for j in range(0, len(N)): n = N[j] # sparse system matrix A, _ = FVConvDiff2D.preprocess(n, L, PE[i], problem, FVSCHEME[i]) # obtain iteration matrix for Jacobi method _, _, _, _, G = SIMPy.solve(A, np.ones(n**2), "jacobi", 1, 0, 1, np.ones(n**2), True) evals_large, _ = eigs(G, 6, which='LM') # 6 largest eigenvalues srGJ = np.max(evals_large) # magnitude of largest is spectral radius OMopt[i, j] = 2. / (1 + np.sqrt(1 - srGJ**2)) # theoretical optimal ## Fit omega_opt(n) = c1/(1+c2*sin(pi/n)) using weighted-least-squares polyfit Ne = np.hstack([N, Nasymp]) # add large number of cells to N # add corresponding ~2 to OMopt OMopte = np.hstack([OMopt, Oasymp * np.ones((len(PE), 1))]) w = Ne # weight factors for polyfit
import FVConvDiff2D import numpy as np import matplotlib.pyplot as plt from matplotlib import cm from scipy.sparse.linalg import spsolve ## Input n = 100 # number of cells along x,y-axis L = 1.0 # size of square in x,y-direction Pe = 10.0 # global Peclet number problem = 1 # problem to solve fvscheme = 'uds-cds' # finite volume scheme ('cds-cds' or 'uds-cds') ## Assemble system matrix A, s = FVConvDiff2D.preprocess(n, L, Pe, problem, fvscheme) ## Do direct solution T = spsolve(A, s.reshape(n*n, order="F")).reshape(n, n, order='F') ## Extend T-field to domain walls and get GHC-residual TT, GHC, _, _ = FVConvDiff2D.postprocess( T, n, L, Pe, problem, fvscheme) ## Plot solution and streamlines of the flow plt.ion() # turn on interactive mode f, axarr = plt.subplots(1, 2, sharey=True) f.suptitle('Convection-diffusion by %s for Pe = %d, \ flux-error = %0.3e' % (fvscheme, Pe, GHC)) # Coordinate arrays
Pe = 10. # global Peclet numbers problem = 1 # problem to solve (set =1) FVSCHEME = ['cds-cds', 'uds-cds'] # finite volume schemes analyzed ## Initialize ERROR = np.zeros((len(N), len(FVSCHEME))) # max. trunc. error array ROC = np.zeros(len(FVSCHEME)) # rate of conv. array TL = np.zeros((len(N), len(FVSCHEME))) # tendency lines array ## Compute max. truncation errors of FV-solutions for all N, PE, FVSCHEME for i in range(0, len(N)): for j in range(0, len(FVSCHEME)): n = N[i] A, s = FVConvDiff2D.preprocess(n, L, Pe, problem, FVSCHEME[j]) # Coordinate arrays dx = L / n # cell size in x,y-direction xf = np.arange(0., L + dx, dx) # cell face coords along x,y-axis xc = np.arange(dx / 2., L, dx) # cell center coordinates along x-axis Xc, _ = np.meshgrid(xc, xc) # 2D cell center x-coordinate array T = spsolve(A, s.reshape(n * n, order="F")) # direct solution # Error T_error = T - Texact(Pe, Xc.reshape(n * n, order="F")) ERROR[i, j] = np.max(np.abs(T_error)) # infinity norm ## Compute rates of convergence TL = np.zeros((len(N), len(FVSCHEME)))
import FVConvDiff2D import numpy as np import matplotlib.pyplot as plt from matplotlib import cm from scipy.sparse.linalg import spsolve ## Input n = 100 # number of cells along x,y-axis L = 1.0 # size of square in x,y-direction Pe = 10.0 # global Peclet number problem = 1 # problem to solve fvscheme = 'uds-cds' # finite volume scheme ('cds-cds' or 'uds-cds') ## Assemble system matrix A, s = FVConvDiff2D.preprocess(n, L, Pe, problem, fvscheme) ## Do direct solution T = spsolve(A, s.reshape(n * n, order="F")).reshape(n, n, order='F') ## Extend T-field to domain walls and get GHC-residual TT, GHC, _, _ = FVConvDiff2D.postprocess(T, n, L, Pe, problem, fvscheme) ## Plot solution and streamlines of the flow plt.ion() # turn on interactive mode f, axarr = plt.subplots(1, 2, sharey=True) f.suptitle('Convection-diffusion by %s for Pe = %d, \ flux-error = %0.3e' % (fvscheme, Pe, GHC)) # Coordinate arrays dx = L / n # cell size in x,y-direction
ERROR = np.zeros((len(TOL), len(N), imax+1)) NUMiter = np.zeros((len(TOL), len(N))) flag = np.zeros((len(TOL), len(N))) ## Time solving linear system of equations jj in range(0, len(N)): for jj in range(0, len(N)): n = N[jj] K = Kvec[jj] ## MULTIGRID ########################################################## # Predetermine grids and preassemble system matrices and store in dict' # for lmg-solver # Assemble system matrix A, s = FVConvDiff2D.preprocess(n, L, Pe, problem, fvscheme) s = s.reshape(n**2, order='F') G = {} # empty dictonary for i in range(0, K): k = K-i # grid level ni = 2**(k+1) # number of grid points # 1D uniform restriction and prologoantion R, _ = lmg.restriction(ni) # restriction for doubling mesh size P, _ = lmg.prolongation(ni) # prolongation for halving mesh size. # extend to 2D using kronecker-product (see below)
Nasymp = 1e8 # large number of cells for asymp. Oasymp = 2-1e-6 # asymp. value for omega_opt(Nasymp) ## Initialize OMopt = np.zeros((len(PE), len(N))) # optimal omega array P = np.zeros((len(PE), 2)) # fitting poly. coeff. for OMopt Ni = np.round(np.logspace(1, 4, 100)) # cell-number vector for tendency curves TC = np.zeros((len(PE), len(Ni))) # tendency curves for OMopt-results ## Compute optimal omega_SOR for coarse grids for i in range(0, len(PE)): for j in range(0, len(N)): n = N[j] # sparse system matrix A, _ = FVConvDiff2D.preprocess(n, L, PE[i], problem, FVSCHEME[i]) # obtain iteration matrix for Jacobi method _, _, _, _, G = SIMPy.solve( A, np.ones(n**2), "jacobi", 1, 0, 1, np.ones(n**2), True) evals_large, _ = eigs(G, 6, which='LM') # 6 largest eigenvalues srGJ = np.max(evals_large) # magnitude of largest is spectral radius OMopt[i, j] = 2. / (1 + np.sqrt(1 - srGJ**2)) # theoretical optimal ## Fit omega_opt(n) = c1/(1+c2*sin(pi/n)) using weighted-least-squares polyfit Ne = np.hstack([N, Nasymp]) # add large number of cells to N # add corresponding ~2 to OMopt OMopte = np.hstack([OMopt, Oasymp*np.ones((len(PE), 1))]) w = Ne # weight factors for polyfit