示例#1
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 single_run(
    problem, basis_, mesh_, bc, t_final, delta_t, num_picard_iterations=None
):
    if num_picard_iterations is None:
        num_picard_iterations = basis_.num_basis_cpts

    imex = imex_runge_kutta.get_time_stepper(basis_.num_basis_cpts)
    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
    )

    matrix_function = lambda t, q: problem.ldg_matrix(
        q, t, bc, bc, bc, bc, include_source=False
    )
    solve_operator = time_stepping.get_solve_function_picard(
        matrix_function, num_picard_iterations, mesh_.num_elems * basis_.num_basis_cpts
    )

    error_dict = dict()

    # def after_step_hook(dg_solution, time):
    #     error = math_utils.compute_error(
    #         dg_solution, lambda x: problem.exact_solution(x, time)
    #     )
    #     error_dict[round(time, 8)] = error

    final_solution = time_stepping.time_step_loop_imex(
        dg_solution,
        0.0,
        t_final,
        delta_t,
        imex,
        explicit_operator,
        implicit_operator,
        solve_operator,
        # after_step_hook
    )

    exact_solution_final = x_functions.FrozenT(problem.exact_solution, t_final)
    error = math_utils.compute_error(final_solution, exact_solution_final)
    return (final_solution, error, error_dict)
def test_imex_linearized_mms():
    # advection with linearized diffusion
    # (q_t + q_x = (f(x, t) q_xx + s(x, t))
    exact_solution = flux_functions.AdvectingSine(amplitude=0.1, offset=0.15)
    p_class = convection_hyper_diffusion.ConvectionHyperDiffusion
    p_func = p_class.linearized_manufactured_solution
    t_initial = 0.0
    bc = boundary.Periodic()
    for diffusion_function in [squared]:
        problem = p_func(exact_solution, None, diffusion_function)
        cfl_list = [0.9, 0.15, 0.1]
        for num_basis_cpts in range(2, 4):
            imex = imex_runge_kutta.get_time_stepper(num_basis_cpts)
            cfl = cfl_list[num_basis_cpts - 1]
            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.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_function = lambda t: problem.ldg_matrix(
                        dg_solution, t, bc, bc, bc, bc, include_source=False)

                    solve_operator = time_stepping.get_solve_function_matrix(
                        matrix_function)

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

                    error = math_utils.compute_error(final_solution,
                                                     exact_solution_final)
                    error_list.append(error)
                    # plot.plot_dg_1d(final_solution, function=exact_solution_final)
                order = utils.convergence_order(error_list)
                with open("hyper_diffusion_linearized_mms_test.yml",
                          "a") as file:
                    dict_ = dict()
                    subdict = dict()
                    subdict["cfl"] = cfl
                    subdict["n"] = n
                    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)
                assert order >= num_basis_cpts
示例#4
0
def test_imex_nonlinear_mms():
    wavenumber = 1.0 / 20.0
    x_left = 0.0
    x_right = 40.0
    exact_solution = flux_functions.AdvectingSine(
        amplitude=0.1, wavenumber=wavenumber, offset=0.15
    )
    p_func = thin_film.ThinFilm.manufactured_solution
    t_initial = 0.0
    bc = boundary.Periodic()
    problem = p_func(exact_solution)
    cfl_list = [0.5, 0.1, 0.1]
    n = 40
    for num_basis_cpts in range(3, 4):
        imex = imex_runge_kutta.get_time_stepper(num_basis_cpts)
        cfl = cfl_list[num_basis_cpts - 1]
        t_final = 10 * cfl * ((x_right - x_left) / 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(x_left, x_right, 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
                )
                matrix_function = lambda t, q: problem.ldg_matrix(
                    q, t, bc, bc, bc, bc, include_source=False
                )

                solve_operator = time_stepping.get_solve_function_picard(
                    matrix_function, num_basis_cpts, num_elems * num_basis_cpts
                )

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

                error = math_utils.compute_error(final_solution, exact_solution_final)
                error_list.append(error)
                # plot.plot_dg_1d(final_solution, function=exact_solution_final)
            with open("thin_film_nonlinear_mms_test.yml", "a") as file:
                dict_ = dict()
                subdict = dict()
                subdict["cfl"] = cfl
                subdict["n"] = n
                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)
            order = utils.convergence_order(error_list)
            assert order >= num_basis_cpts