Beispiel #1
0
def test_linearized_mms_ldg_convergence():
    # LDG Diffusion should converge at 1st order for 1 basis_cpt
    # or at num_basis_cpts - 2 for more basis_cpts
    t = 0.0
    bc = boundary.Periodic()
    p_class = convection_hyper_diffusion.NonlinearHyperDiffusion
    p_func = p_class.linearized_manufactured_solution
    exact_solution = flux_functions.AdvectingSine(offset=2.0)
    for diffusion_function in diffusion_functions:
        problem = p_func(exact_solution, diffusion_function)
        exact_time_derivative = problem.exact_time_derivative(
            exact_solution, t)
        for num_basis_cpts in [1] + list(range(5, 6)):
            for basis_class in basis.BASIS_LIST:
                error_list = []
                basis_ = basis_class(num_basis_cpts)
                # 10 and 20 elems maybe not in asymptotic regime yet
                for num_elems in [20, 40]:
                    mesh_ = mesh.Mesh1DUniform(0.0, 1.0, num_elems)
                    dg_solution = basis_.project(exact_solution, mesh_, t)
                    L = problem.ldg_operator(dg_solution, t, bc, bc)
                    dg_error = math_utils.compute_dg_error(
                        L, exact_time_derivative)
                    error = dg_error.norm()
                    error_list.append(error)
                    # plot.plot_dg_1d(L, function=exact_time_derivative)
                order = utils.convergence_order(error_list)
                # if already at machine precision don't check convergence
                if error_list[-1] > tolerance:
                    if num_basis_cpts == 1:
                        assert order >= 1
                    else:
                        assert order >= num_basis_cpts - 4
def test_ldg_polynomials_convergence():
    # LDG Diffusion should converge at 1st order for 1 basis_cpt
    # or at num_basis_cpts - 4 for more basis_cpts
    bc = boundary.Extrapolation()
    t = 0.0
    for i in range(4, 7):
        hyper_diffusion.initial_condition = x_functions.Polynomial(degree=i)
        exact_solution = hyper_diffusion.exact_time_derivative(
            hyper_diffusion.initial_condition, t)
        for num_basis_cpts in [1] + list(range(5, i + 1)):
            for basis_class in basis.BASIS_LIST:
                error_list = []
                basis_ = basis_class(num_basis_cpts)
                for num_elems in [10, 20]:
                    mesh_ = mesh.Mesh1DUniform(0.0, 1.0, num_elems)
                    dg_solution = basis_.project(
                        hyper_diffusion.initial_condition, mesh_)
                    L = hyper_diffusion.ldg_operator(dg_solution, t, bc, bc,
                                                     bc, bc)
                    dg_error = math_utils.compute_dg_error(L, exact_solution)
                    error = dg_error.norm(slice(2, -2))
                    error_list.append(error)
                    # plot.plot_dg_1d(L, function=exact_solution, elem_slice=slice(1, -1))
                order = utils.convergence_order(error_list)
                # if already at machine precision don't check convergence
                if error_list[-1] > tolerance:
                    if num_basis_cpts == 1:
                        assert order >= 1
                    else:
                        assert order >= num_basis_cpts - 4
Beispiel #3
0
def test_ldg_cos():
    # LDG Diffusion should converge at 1st order for 1 basis_cpt
    # or at num_basis_cpts - 4 for more basis_cpts
    t = 0.0
    bc = boundary.Periodic()
    for nonlinear_hyper_diffusion in [hyper_diffusion_identity]:
        nonlinear_hyper_diffusion.initial_condition = x_functions.Cosine(
            offset=2.0)
        exact_solution = nonlinear_hyper_diffusion.exact_time_derivative(
            nonlinear_hyper_diffusion.initial_condition, t)
        for num_basis_cpts in [1] + list(range(5, 6)):
            for basis_class in basis.BASIS_LIST:
                error_list = []
                basis_ = basis_class(num_basis_cpts)
                for num_elems in [10, 20]:
                    mesh_ = mesh.Mesh1DUniform(0.0, 1.0, num_elems)
                    dg_solution = basis_.project(
                        nonlinear_hyper_diffusion.initial_condition, mesh_)
                    L = nonlinear_hyper_diffusion.ldg_operator(
                        dg_solution, t, bc, bc, bc, bc)
                    dg_error = math_utils.compute_dg_error(L, exact_solution)
                    error = dg_error.norm()
                    error_list.append(error)
                    # plot.plot_dg_1d(L, function=exact_solution)
                order = utils.convergence_order(error_list)
                # if already at machine precision don't check convergence
                if error_list[-1] > tolerance:
                    if num_basis_cpts == 1:
                        assert order >= 1
                    else:
                        assert order >= num_basis_cpts - 4
Beispiel #4
0
def test_imex_linear_diffusion():
    # advection with linear diffusion
    # (q_t + q_x = q_xx + s(x, t))
    exact_solution = xt_functions.AdvectingSine(offset=2.0)
    problem = convection_diffusion.ConvectionDiffusion.manufactured_solution(
        exact_solution)
    t_initial = 0.0
    bc = boundary.Periodic()
    error_dict = dict()
    cfl_list = [0.9, 0.3, 0.1]
    for num_basis_cpts in range(1, 4):
        imex = imex_runge_kutta.get_time_stepper(num_basis_cpts)
        cfl = cfl_list[num_basis_cpts - 1]
        # take 10 timesteps at coarsest time interval
        n = 20
        t_final = cfl * (1.0 / n) / exact_solution.wavespeed
        exact_solution_final = lambda x: exact_solution(x, t_final)
        for basis_class in basis.BASIS_LIST:
            basis_ = basis_class(num_basis_cpts)
            error_list = []
            for num_elems in [n, 2 * n]:
                mesh_ = mesh.Mesh1DUniform(0.0, 1.0, num_elems)
                delta_t = cfl * mesh_.delta_x / exact_solution.wavespeed
                dg_solution = basis_.project(problem.initial_condition, mesh_)

                # weak dg form with flux_function and source term
                explicit_operator = problem.get_explicit_operator(bc)
                # ldg discretization of diffusion_function
                implicit_operator = problem.get_implicit_operator(
                    bc, bc, include_source=False)
                # this is a constant matrix case
                (matrix, vector) = problem.ldg_matrix(dg_solution,
                                                      t_initial,
                                                      bc,
                                                      bc,
                                                      include_source=False)
                solve_operator = time_stepping.get_solve_function_constant_matrix(
                    matrix, vector)

                final_solution = time_stepping.time_step_loop_imex(
                    dg_solution,
                    t_initial,
                    t_final,
                    delta_t,
                    imex,
                    explicit_operator,
                    implicit_operator,
                    solve_operator,
                )

                dg_error = math_utils.compute_dg_error(final_solution,
                                                       exact_solution_final)
                error = dg_error.norm()
                error_list.append(error)
                # plot.plot_dg_1d(final_solution, function=exact_solution_final)
                # plot.plot_dg_1d(dg_error)
            error_dict[num_basis_cpts] = error_list
            order = utils.convergence_order(error_list)
            assert order >= num_basis_cpts
def test_compute_dg_error():
    f = lambda x: np.cos(x)
    for basis_class in basis.BASIS_LIST:
        for num_basis_cpts in range(1, 3):
            basis_ = basis_class(num_basis_cpts)
            mesh_ = mesh.Mesh1DUniform(0.0, 1.0, 10)
            dg_solution = basis_.project(f, mesh_)
            dg_error = math_utils.compute_dg_error(dg_solution, f)
            print(dg_error)
def test_ldg_matrix_irk():
    p_func = convection_hyper_diffusion.HyperDiffusion.periodic_exact_solution
    problem = p_func(x_functions.Sine(offset=2.0), diffusion_constant=1.0)
    t_initial = 0.0
    t_final = 0.1
    bc = boundary.Periodic()
    exact_solution = lambda x: problem.exact_solution(x, t_final)
    for num_basis_cpts in range(1, 3):
        irk = implicit_runge_kutta.get_time_stepper(num_basis_cpts)
        for basis_class in basis.BASIS_LIST:
            basis_ = basis_class(num_basis_cpts)
            error_list = []
            # constant matrix
            n = 20
            for num_elems in [n, 2 * n]:
                mesh_ = mesh.Mesh1DUniform(0.0, 1.0, num_elems)
                delta_t = mesh_.delta_x / 5
                dg_solution = basis_.project(problem.initial_condition, mesh_)
                # constant matrix time doesn't matter
                tuple_ = problem.ldg_matrix(dg_solution, t_initial, bc, bc, bc,
                                            bc)
                matrix = tuple_[0]
                vector = tuple_[1]
                rhs_function = problem.get_implicit_operator(bc, bc, bc, bc)
                solve_function = time_stepping.get_solve_function_constant_matrix(
                    matrix, vector)
                new_solution = time_stepping.time_step_loop_implicit(
                    dg_solution,
                    t_initial,
                    t_final,
                    delta_t,
                    irk,
                    rhs_function,
                    solve_function,
                )
                dg_error = math_utils.compute_dg_error(new_solution,
                                                       exact_solution)
                error = dg_error.norm()
                error_list.append(error)
                # plot.plot_dg_1d(new_solution, function=exact_solution)
                # plot.plot(dg_error)
            order = utils.convergence_order(error_list)
            # if not already at machine error
            if error_list[0] > 1e-10 and error_list[1] > 1e-10:
                assert order >= num_basis_cpts
def test_diffusion_ldg_polynomials_exact():
    # LDG Diffusion should be exactly second derivative of polynomials in the interior
    bc = boundary.Extrapolation()
    t = 0.0
    # x^i should be exact for i+1 or more basis_cpts
    for i in range(2, 5):
        diffusion.initial_condition = x_functions.Polynomial(degree=i)
        exact_solution = diffusion.exact_time_derivative(
            diffusion.initial_condition, t)
        for num_basis_cpts in range(i + 1, 6):
            for basis_class in basis.BASIS_LIST:
                basis_ = basis_class(num_basis_cpts)
                mesh_ = mesh.Mesh1DUniform(0.0, 1.0, 10)
                dg_solution = basis_.project(diffusion.initial_condition,
                                             mesh_)
                L = diffusion.ldg_operator(dg_solution, t, bc, bc)
                dg_error = math_utils.compute_dg_error(L, exact_solution)
                error = dg_error.norm(slice(1, -1))
                # plot.plot_dg_1d(dg_error, elem_slice=slice(1, -1))
                assert error < tolerance
def test_diffusion_ldg_polynomials_convergence():
    # LDG Diffusion should converge at 1st order for 1 basis_cpt
    # or at num_basis_cpts - 2 for more basis_cpts
    bc = boundary.Extrapolation()
    t = 0.0
    for nonlinear_diffusion in test_problems:
        d = nonlinear_diffusion.diffusion_function.degree
        # having problems at i >= d with convergence rate
        # still small error just not converging properly
        # exact solution is grows rapidly as x increases in this situation
        # error must larger at x = 1 then at x = 0
        # could also not be in asymptotic regime
        for i in range(1, d):
            nonlinear_diffusion.initial_condition = x_functions.Polynomial(
                degree=i)
            exact_solution = nonlinear_diffusion.exact_time_derivative(
                nonlinear_diffusion.initial_condition, t)
            for num_basis_cpts in [1] + list(range(3, i + 1)):
                for basis_class in basis.BASIS_LIST:
                    error_list = []
                    basis_ = basis_class(num_basis_cpts)
                    for num_elems in [30, 60]:
                        mesh_ = mesh.Mesh1DUniform(0.0, 1.0, num_elems)
                        dg_solution = basis_.project(
                            nonlinear_diffusion.initial_condition, mesh_)
                        L = nonlinear_diffusion.ldg_operator(
                            dg_solution, t, bc, bc)
                        dg_error = math_utils.compute_dg_error(
                            L, exact_solution)
                        error = dg_error.norm(slice(1, -1))
                        error_list.append(error)
                        # plot.plot_dg_1d(
                        #     L, function=exact_solution, elem_slice=slice(1, -1)
                        # )
                    order = utils.convergence_order(error_list)
                    # if already at machine precision don't check convergence
                    if error_list[-1] > tolerance:
                        if num_basis_cpts == 1:
                            assert order >= 1
                        else:
                            assert order >= num_basis_cpts - 2
Beispiel #9
0
def test_ldg_polynomials_exact():
    # LDG HyperDiffusion should be exact for polynomials in the interior
    bc = boundary.Extrapolation()
    t = 0.0
    # x^i should be exact for i+1 or more basis_cpts
    # needs lot more basis components if f(q, x, t) = q^2
    for nonlinear_hyper_diffusion in [hyper_diffusion_identity]:
        for i in range(3, 5):
            nonlinear_hyper_diffusion.initial_condition = x_functions.Polynomial(
                degree=i)
            exact_solution = nonlinear_hyper_diffusion.exact_time_derivative(
                nonlinear_hyper_diffusion.initial_condition, t)
            for num_basis_cpts in range(i + 1, 6):
                for basis_class in basis.BASIS_LIST:
                    basis_ = basis_class(num_basis_cpts)
                    mesh_ = mesh.Mesh1DUniform(0.0, 1.0, 10)
                    dg_solution = basis_.project(
                        nonlinear_hyper_diffusion.initial_condition, mesh_)
                    L = nonlinear_hyper_diffusion.ldg_operator(
                        dg_solution, t, bc, bc, bc, bc)
                    dg_error = math_utils.compute_dg_error(L, exact_solution)
                    error = dg_error.norm(slice(2, -2))
                    # plot.plot_dg_1d(L, function=exact_solution, elem_slice=slice(1, -1))
                    assert error < tolerance
Beispiel #10
0
def test_ldg_polynomials_convergence():
    # LDG Diffusion should converge at 1st order for 1 basis_cpt
    # or at num_basis_cpts - 4 for more basis_cpts
    bc = boundary.Extrapolation()
    t = 0.0
    # having problems at i >= 3 with convergence rate
    # still small error just not converging properly
    for i in range(3, 5):
        thin_film_diffusion.initial_condition = x_functions.Polynomial(degree=i)
        thin_film_diffusion.initial_condition.set_coeff((1.0 / i), i)
        exact_solution = thin_film_diffusion.exact_time_derivative(
            thin_film_diffusion.initial_condition, t
        )
        for num_basis_cpts in [1] + list(range(5, 6)):
            for basis_class in basis.BASIS_LIST:
                error_list = []
                basis_ = basis_class(num_basis_cpts)
                for num_elems in [40, 80]:
                    mesh_ = mesh.Mesh1DUniform(0.0, 1.0, num_elems)
                    dg_solution = basis_.project(
                        thin_film_diffusion.initial_condition, mesh_
                    )
                    L = thin_film_diffusion.ldg_operator(dg_solution, t, bc, bc, bc, bc)
                    dg_error = math_utils.compute_dg_error(L, exact_solution)
                    error = dg_error.norm(slice(2, -2))
                    error_list.append(error)
                    # plot.plot_dg_1d(
                    #     L, function=exact_solution, elem_slice=slice(1, -1)
                    # )
                order = utils.convergence_order(error_list)
                # if already at machine precision don't check convergence
                if error_list[-1] > tolerance and error_list[0] > tolerance:
                    if num_basis_cpts == 1:
                        assert order >= 1
                    else:
                        assert order >= num_basis_cpts - 4
def test_imex_linear_diffusion():
    # advection with linear diffusion
    # (q_t + q_x = -q_xxxx + s(x, t))
    exact_solution = flux_functions.AdvectingSine(offset=2.0)
    p_class = convection_hyper_diffusion.ConvectionHyperDiffusion
    diffusion_constant = 0.05
    diffusion_function = flux_functions.Polynomial([diffusion_constant])
    problem = p_class.manufactured_solution(
        exact_solution, diffusion_function=diffusion_function)
    t_initial = 0.0
    bc = boundary.Periodic()
    cfl_list = [0.9, 0.3, 0.1]
    for num_basis_cpts in range(1, 4):
        imex = imex_runge_kutta.get_time_stepper(num_basis_cpts)
        n = 20
        cfl = cfl_list[num_basis_cpts - 1]
        t_final = cfl * (1.0 / n) / exact_solution.wavespeed
        exact_solution_final = lambda x: exact_solution(x, t_final)
        for basis_class in [basis.LegendreBasis1D]:
            basis_ = basis_class(num_basis_cpts)
            error_list = []
            for num_elems in [n, 2 * n]:
                mesh_ = mesh.Mesh1DUniform(0.0, 1.0, num_elems)
                delta_t = cfl * mesh_.delta_x / exact_solution.wavespeed
                dg_solution = basis_.project(problem.initial_condition, mesh_)

                # weak dg form with flux_function and source term
                explicit_operator = problem.get_explicit_operator(bc)
                # ldg discretization of diffusion_function
                implicit_operator = problem.get_implicit_operator(
                    bc, bc, bc, bc, include_source=False)
                # this is a constant matrix case
                (matrix, vector) = problem.ldg_matrix(dg_solution,
                                                      t_initial,
                                                      bc,
                                                      bc,
                                                      bc,
                                                      bc,
                                                      include_source=False)
                solve_operator = time_stepping.get_solve_function_constant_matrix(
                    matrix, vector)

                final_solution = time_stepping.time_step_loop_imex(
                    dg_solution,
                    t_initial,
                    t_final,
                    delta_t,
                    imex,
                    explicit_operator,
                    implicit_operator,
                    solve_operator,
                )

                dg_error = math_utils.compute_dg_error(final_solution,
                                                       exact_solution_final)
                error = dg_error.norm()
                error_list.append(error)
                # plot.plot_dg_1d(final_solution, function=exact_solution_final)
                # plot.plot_dg_1d(dg_error)
            order = utils.convergence_order(error_list)
            with open("hyper_diffusion_linear_test.yml", "a") as file:
                dict_ = dict()
                subdict = dict()
                subdict["cfl"] = cfl
                subdict["n"] = n
                subdict["diffusion_constant"] = diffusion_constant
                subdict["error0"] = float(error_list[0])
                subdict["error1"] = float(error_list[1])
                subdict["order"] = float(np.log2(error_list[0] /
                                                 error_list[1]))
                dict_[num_basis_cpts] = subdict
                yaml.dump(dict_, file, default_flow_style=False)
            if error_list[0] > 1e-10 and error_list[1] > 1e-10:
                assert order >= num_basis_cpts