def V_cycle(u, f, h, v1, v2, Laplacians):
    #presmooth v1 times
    u = GS_RBBR_smoother(u, f, h, v1)

    #access correct Laplacian
    L = Laplacians[int(-2 - np.log2(h))]

    #compute residual
    res = compute_residual(u, f, h, L)

    #restrict residual
    res2 = full_weighting_restriction(res, h)

    #solve for coarse grid error, check grid level to decide whether to solve or be recursive
    if h == 2**(-2):
        error = trivial_direct_solve(res2, 2 * h)
    else:
        error = np.zeros((int(1 / (2 * h) + 1), int(1 / (2 * h) + 1)),
                         dtype=float)
        error = V_cycle(error, res2, 2 * h, v1, v2, Laplacians)

    #interpolate error
    error2 = bilinear_interpolation(error, 2 * h)

    #correct (add error back in)
    u = u + error2

    #post-smooth v2 times
    u = GS_RBBR_smoother(u, f, h, v2)

    return u
Beispiel #2
0
def main():
    #test problem grid spacing size
    h = 2**(-7)
    n = int(1 / h - 1)

    #initialize 0th iterate u
    u = np.zeros((n + 2, n + 2))

    #compute a known solution
    SOL = known_solution(h)

    #make sparse Laplacians for later computation
    Laplacians = []
    for i in range(2, 10):
        Laplacians.append(get_Laplacian(2**(-i)))

    #generate a RHS that SOL is the solution to the algebraic eqn Lu = f
    f = apply_Laplacian(SOL, h, Laplacians[int(-2 - np.log2(h))])

    #initialize the error vector between our known solution SOL and 0th iterate u
    init_error = np.amax(np.abs(SOL - u))

    #tolerance for stopping criterion
    tol = 10**(-10)

    #smoothing step counts to check over
    smooth_steps = [(0, 1), (1, 0), (1, 1), (0, 2), (2, 0), (1, 2), (2, 1),
                    (3, 0), (0, 3), (2, 2), (1, 3), (3, 1), (4, 0), (0, 4)]
    step_number = 0
    conv_Factor = np.zeros((15, 8))
    itcounts = np.zeros(15)
    times = np.zeros(15)

    for step in tqdm(smooth_steps):
        errors = [init_error]
        u = np.zeros((n + 2, n + 2))
        #do multigrid iteration
        itcount = 0
        tic = clock()
        while True:
            u_old = u + 0
            itcount += 1
            #use a V-cycle iteration with smoothing steps as given
            u = V_cycle(u_old, f, h, step[0], step[1], Laplacians)
            res = compute_residual(u, f, h, Laplacians[int(-2 - np.log2(h))])

            #calculate convergence factor
            error_k = np.amax(np.abs(SOL - u))
            errors.append(error_k)

            #stop when iterate differences within relative tol
            if np.amax(np.abs(res)) < tol * np.amax(np.abs(f)):
                break

        toc = clock()
        print toc - tic

        #compute convergence factors
        conv_factors = [(errors[k] / errors[0])**(1 / k) for k in range(1, 6)]
        #save data for table
        for i in range(5):
            conv_Factor[step_number][i] = conv_factors[i]
        itcounts[step_number] = itcount
        times[step_number] = toc - tic

        step_number += 1

        # print errors[itcount]

    #create table of output data
    print "h = ", h
    print "tol =", tol
    smoothing_table = [[
        smooth_steps[i], conv_Factor[i][0], conv_Factor[i][1],
        conv_Factor[i][2], conv_Factor[i][3], conv_Factor[i][4], itcounts[i],
        times[i]
    ] for i in range(14)]
    print tabulate.tabulate(smoothing_table,
                            headers=[
                                "v1, v2", "ave of 1", "average of 2",
                                "average of 3", "average of 4", "average of 5",
                                "iterations", "run times"
                            ],
                            tablefmt="latex")
Beispiel #3
0
def main():
	#create grid spacings data
	grid_spacings = [2**(-4), 2**(-5), 2**(-6), 2**(-7), 2**(-8)]

	#make sparse Laplacians for later computation
	Laplacians = []
	for i in range(2,10):
		Laplacians.append(get_Laplacian(2**(-i)))
	
	#create iteration count holder and runtimes holder
	itcounts = []
	times = []

	#get command line input, for test case
	args = PARSE_ARGS()

	#set tolerance for stopping criterion
	tol = 10**(-7)

	#in case we're running the multigrid code test on known problem
	if args.test:
		errors=[]
		grid_spacings = [2**(-8)]

	#loop over different grid spacings
	for h in tqdm(grid_spacings):
		#time multigrid code for grid spacing h
		toc = clock()

		#set up initial solution guess
		n = int(1/h - 1)
		u = np.zeros((n+2, n+2), dtype=float)
	
		#if in test, set known solution and get RHS
		if args.test:
			SOL = np.random.rand(n,n)
			SOL = np.pad(SOL, ((1,1),(1,1)), mode='constant')
			f = apply_Laplacian_nomatrix(SOL,h, Laplacians[int(-2-np.log2(h))])
		#if not in test, set RHS as in problem statement
		else:
			f = RHS_function_sampled(h)

		#use multigrid algorithm
		itcount = 0
		while True:
			itcount += 1
			print itcount
			#use a V-cycle iteration
			u=V_cycle(u, f, h, 1,1, Laplacians)

			#compute residual of solution
			res = compute_residual(u, f, h, Laplacians[int(-2-np.log2(h))])

			#check convergence using norm of residual relative to norm of RHS function
			if np.amax(np.abs(res)) < tol*np.amax(np.abs(f)):
				break

		#stop timer, collect time and iteration count into data table
		tic = clock()
		itcounts.append(itcount)
		times.append(tic-toc)

		#if in test case, collect error for table
		if args.test:
			errors.append(np.amax(np.abs(u-SOL))/np.amax(np.abs(SOL)))

	#create table of output data for test case and for problem solution
	if args.test:
		test_table = [[grid_spacings[i], itcounts[i], times[i], errors[i]] for i in range(np.size(grid_spacings)) ]
		print tabulate.tabulate(test_table, headers = ["grid spacing h", "iteration count", "run time (seconds)", "max errors"], tablefmt="latex")
	
	else:	
		table = [[grid_spacings[i], itcounts[i], times[i]] for i in range(np.size(grid_spacings)) ]
		print tabulate.tabulate(table, headers = ["grid spacing h", "iteration count", "run time (seconds)"], tablefmt="latex")
Beispiel #4
0
def main():
    h = 2**(-6)
    n = int(1 / h - 1)
    u = np.zeros((n + 2, n + 2))
    f = RHS_function_sampled(h)
    u_known = known_solution(h)

    init_error = np.amax(np.abs(u_known - u))

    #make sparse Laplacians for later computation
    Laplacians = []
    for i in range(2, 10):
        Laplacians.append(get_Laplacian(2**(-i)))

    tol = 10**(-7)

    step_number = 0
    #smoothing step counts to check over
    smooth_steps = [(0, 1), (1, 0), (1, 1), (0, 2), (2, 0), (1, 2), (2, 1),
                    (3, 0), (0, 3), (2, 2), (1, 3), (3, 1), (4, 0), (0, 4)]
    conv_Factor = np.zeros((15, 8))
    itcounts = np.zeros(15)
    times = np.zeros(15)

    for step in tqdm(smooth_steps):
        errors = [init_error]
        u = np.zeros((n + 2, n + 2))
        #do multigrid iteration
        itcount = 0
        tic = clock()
        while True:
            u_old = u + 0
            itcount += 1
            #use a V-cycle iteration with smoothing steps as given
            u = V_cycle(u_old, f, h, step[0], step[1], Laplacians)
            res = compute_residual(u, f, h, Laplacians[int(-2 - np.log2(h))])

            #add error at this iterate to list of errors
            errors.append(np.amax(np.abs(u_known - u)))

            #stop when iterate differences within relative tol
            if np.amax(np.abs(res)) < tol * np.amax(np.abs(f)):
                break

        toc = clock()
        # print toc-tic

        #compute convergence factors
        conv_factors = [(errors[k] / errors[0])**(1 / k) for k in range(1, 6)]
        #save data for table
        for i in range(5):
            conv_Factor[step_number][i] = conv_factors[i]
        itcounts[step_number] = itcount
        times[step_number] = toc - tic

        step_number += 1

        # print errors[itcount]

    #create table of output data
    print "h = ", h
    print "tol =", tol
    smoothing_table = [[
        smooth_steps[i], conv_Factor[i][0], conv_Factor[i][1],
        conv_Factor[i][2], conv_Factor[i][3], conv_Factor[i][4], itcounts[i],
        times[i]
    ] for i in range(14)]
    print tabulate.tabulate(smoothing_table,
                            headers=[
                                "v1, v2", "ave of 1", "average of 2",
                                "average of 3", "average of 4", "average of 5",
                                "iterations", "run times"
                            ],
                            tablefmt="latex")