def __init__(self, wavespeed=1.0, initial_condition=None, source_function=None):
        self.wavespeed = wavespeed
        if initial_condition is None:
            self.initial_condition = x_functions.Sine()
        else:
            self.initial_condition = initial_condition

        app = advection.Advection(wavespeed, source_function)
        max_wavespeed = wavespeed
        exact_solution = advection.ExactSolution(initial_condition, wavespeed)

        super().__init__(
            app, initial_condition, max_wavespeed, exact_solution
        )
Example #2
0
def test_advection_operator():
    # test that dg_operator acting on projected initial condition converges to
    # exact time derivative
    # will lose one order of accuracy

    for i in range(2):
        if i == 0:
            sin = x_functions.Sine()
            cos = x_functions.Cosine()
            initial_condition = x_functions.ComposedVector([sin, cos])
        else:
            initial_condition = x_functions.Sine()
        wavespeed = 1.0
        exact_solution = advection.ExactSolution(initial_condition, wavespeed)
        exact_time_derivative = advection.ExactTimeDerivative(exact_solution, wavespeed)
        initial_time_derivative = x_functions.FrozenT(exact_time_derivative, 0.0)

        app_ = advection.Advection(wavespeed)
        riemann_solver = riemann_solvers.LocalLaxFriedrichs(app_.flux_function)
        boundary_condition = boundary.Periodic()

        for basis_class in basis.BASIS_LIST:
            for num_basis_cpts in range(1, 5):
                basis_ = basis_class(num_basis_cpts)
                error_list = []
                for num_elems in [20, 40]:
                    mesh_ = mesh.Mesh1DUniform(0.0, 1.0, num_elems)
                    dg_sol = basis_.project(initial_condition, mesh_)
                    dg_operator = app_.get_explicit_operator(
                        riemann_solver, boundary_condition
                    )
                    F = dg_operator(0.0, dg_sol)
                    error = math_utils.compute_error(F, initial_time_derivative)
                    error_list.append(error)

                order = utils.convergence_order(error_list)
                assert order >= max([1.0, num_basis_cpts - 1])
Example #3
0
def test_solution_operations():
    # TODO: test operating two solutions with different bases
    cos = x_functions.Cosine()
    sin = x_functions.Sine()
    cos_sol = basis_.project(cos, mesh_)
    sin_sol = basis_.project(sin, mesh_)
    cosp2_sol = cos_sol + 2.0
    sinp2_sol = sin_sol + 2.0

    # addition
    def func(x):
        return cos(x) + 2.0 + sin(x) + 2.0
    new_sol = cosp2_sol + sinp2_sol
    projected_sol = basis_.project(func, mesh_)
    error = (new_sol - projected_sol).norm()
    assert error <= tolerance

    # subtraction
    def func(x):
        return cos(x) + 2.0 - (sin(x) + 2.0)
    new_sol = cosp2_sol - sinp2_sol
    projected_sol = basis_.project(func, mesh_)
    error = (new_sol - projected_sol).norm()
    assert error <= tolerance

    # multiplication, division, and power won't be exact
    # multiplication
    def func(x):
        return (cos(x) + 2.0) * (sin(x) + 2.0)
    new_sol = cosp2_sol * sinp2_sol
    projected_sol = basis_.project(func, mesh_)
    error = (new_sol - projected_sol).norm()
    assert error <= tolerance_2

    # division
    def func(x):
        return (cos(x) + 2.0) / (sin(x) + 2.0)
    new_sol = cosp2_sol / sinp2_sol
    projected_sol = basis_.project(func, mesh_)
    error = (new_sol - projected_sol).norm()
    assert error <= tolerance_2

    # power
    def func(x):
        return (cos(x) + 2.0) ** (sin(x) + 2.0)
    new_sol = cosp2_sol ** sinp2_sol
    projected_sol = basis_.project(func, mesh_)
    error = (new_sol - projected_sol).norm()
    assert error <= tolerance_2
Example #4
0
def test_bounds_limiter_sine():
    bounds_limiter = shock_capturing_limiters.BoundsLimiter()

    basis_ = basis.LegendreBasis1D(3)
    mesh_ = mesh.Mesh1DUniform(0, 1, 10)
    func = x_functions.Sine(1.0, 1.0, 0.0)
    dg_solution = basis_.project(func, mesh_)

    boundary_condition = boundary.Periodic()
    app_ = advection.Advection()
    problem_ = problem.Problem(app_, dg_solution)
    problem_.boundary_condition = boundary_condition

    initial_solution = dg_solution.copy()
    limited_solution = bounds_limiter.limit_solution(problem, dg_solution)
    # limited solution should be same as initial solution as smooth
    assert (limited_solution - initial_solution).norm() == 0.0

    func = x_functions.Sine(1.0, 10.0, 0.0)
    dg_solution = basis_.project(func, mesh_)
    initial_solution = dg_solution.copy()
    limited_solution = bounds_limiter.limit_solution(problem, dg_solution)
    # with higher wavenumber the limiter should chop off maxima
    assert limited_solution.norm() <= initial_solution.norm()
 def periodic_exact_solution(wavenumber=1.0, diffusion_constant=1.0):
     # q_t(x, t) - d * q_xx(x, t) = 0
     # q(x, 0) = sin(2 pi lambda x)
     # q(n, t) = q(m, t), q_x(n, t) = q_x(m, t) for integers n < m
     # exact solution with periodic boundaries
     # q(x, t) = e^{-4 pi^2 lambda^2 t} sin(2 pi lambda x)
     initial_condition = x_functions.Sine(wavenumber)
     diffusion = Diffusion(
         initial_condition=initial_condition, diffusion_constant=diffusion_constant
     )
     r = -4.0 * diffusion_constant * np.power(np.pi * wavenumber, 2)
     diffusion.exact_solution = xt_functions.ExponentialFunction(
         initial_condition, r
     )
     return diffusion
def test_linearized_mms_ldg_matrix_independence_from_dg_solution():
    g = x_functions.Sine(offset=2.0)
    r = -4.0 * np.power(np.pi, 2)
    exact_solution = flux_functions.ExponentialFunction(g, r)
    t_initial = 0.0
    bc = boundary.Periodic()
    p_func = convection_diffusion.NonlinearDiffusion.linearized_manufactured_solution
    for diffusion_function in diffusion_functions:
        problem = p_func(exact_solution, diffusion_function)
        for basis_class in basis.BASIS_LIST:
            for num_basis_cpts in range(1, 4):
                basis_ = basis_class(num_basis_cpts)
                mesh_ = mesh.Mesh1DUniform(0.0, 1.0, 20)
                sine_dg = basis_.project(x_functions.Sine(offset=2.0), mesh_)
                cosine_dg = basis_.project(x_functions.Cosine(offset=2.0),
                                           mesh_)
                tuple_ = problem.ldg_matrix(sine_dg, t_initial, bc, bc)
                sine_matrix = tuple_[0]
                sine_vector = tuple_[1]
                tuple_ = problem.ldg_matrix(cosine_dg, t_initial, bc, bc)
                cosine_matrix = tuple_[0]
                cosine_vector = tuple_[1]
                assert np.linalg.norm(sine_matrix - cosine_matrix) <= tolerance
                assert np.linalg.norm(sine_vector - cosine_vector) <= tolerance
def test_ldg_operator_equal_matrix():
    f = x_functions.Sine()
    t = 0.0
    for bc in [boundary.Periodic(), boundary.Extrapolation()]:
        for num_basis_cpts in range(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(f, mesh_)
                L = diffusion.ldg_operator(dg_solution, t, bc, bc)
                dg_vector = dg_solution.to_vector()
                tuple_ = diffusion.ldg_matrix(dg_solution, t, bc, bc)
                matrix = tuple_[0]
                vector = tuple_[1]
                error = np.linalg.norm(L.to_vector() -
                                       np.matmul(matrix, dg_vector) - vector)
                assert error <= tolerance
Example #8
0
def test_neumann():
    boundary_derivative_function = flux_functions.Zero()
    bc = boundary.Neumann(boundary_derivative_function)

    basis_ = basis.LegendreBasis1D(3)
    mesh_ = mesh.Mesh1DUniform(0.0, 1.0, 10)
    f = x_functions.Sine()
    dg_solution = basis_.project(f, mesh_)
    problem = smooth_scalar_example.SmoothScalarExample(1.0, f)

    riemann_solver = riemann_solvers.LocalLaxFriedrichs(problem)
    boundary_faces = mesh_.boundary_faces
    t = 0.0

    flux = bc.evaluate_boundary(dg_solution, boundary_faces[0], riemann_solver,
                                t)
    assert flux is not None
Example #9
0
def test_interior():
    bc = boundary.Extrapolation()

    basis_ = basis.LegendreBasis1D(3)
    mesh_ = mesh.Mesh1DUniform(0.0, 1.0, 10)
    f = x_functions.Sine()
    dg_solution = basis_.project(f, mesh_)
    problem = smooth_scalar_example.SmoothScalarExample(1.0, f)

    riemann_solver = riemann_solvers.LocalLaxFriedrichs(problem)
    boundary_faces = mesh_.boundary_faces
    t = 0.0

    flux = bc.evaluate_boundary(dg_solution, boundary_faces[0], riemann_solver,
                                t)
    x = mesh_.get_face_position(boundary_faces[0])
    assert flux == dg_solution(x)
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
Example #11
0
def test_periodic():
    bc = boundary.Periodic()
    basis_ = basis.LegendreBasis1D(3)
    mesh_ = mesh.Mesh1DUniform(0.0, 1.0, 10)

    f = x_functions.Sine()
    dg_solution = basis_.project(f, mesh_)
    problem = smooth_scalar_example.SmoothScalarExample(1.0, f)

    riemann_solver = riemann_solvers.LocalLaxFriedrichs(problem)
    boundary_faces = mesh_.boundary_faces
    t = 0.0

    flux_0 = bc.evaluate_boundary(dg_solution, boundary_faces[0],
                                  riemann_solver, t)
    flux_1 = bc.evaluate_boundary(dg_solution, boundary_faces[1],
                                  riemann_solver, t)
    # fluxes should be the same
    assert flux_0 == flux_1
Example #12
0
def test_exponential_function():
    g = x_functions.Sine()
    r = 1.0
    xt_function = xt_functions.ExponentialFunction(g, r)
    utils.check_to_from_dict(xt_function, xt_functions)
    # should be able to call with (x, t) and (q, x, t)
    q = 0.0
    x = 0.5
    t = 0.1
    assert xt_function(x, t) is not None
    assert xt_function(q, x, t) is not None
    assert xt_function(q, x, t) == xt_function(x, t)
    assert xt_function.q_derivative(q, x, t) is not None
    assert xt_function.x_derivative(q, x, t) is not None
    assert xt_function.x_derivative(x, t) is not None
    assert xt_function.x_derivative(x, t) == xt_function.x_derivative(q, x, t)
    assert xt_function.t_derivative(q, x, t) is not None
    assert xt_function.t_derivative(x, t) is not None
    assert xt_function.t_derivative(x, t) == xt_function.t_derivative(q, x, t)
Example #13
0
    def periodic_exact_solution(initial_condition=None, diffusion_constant=1.0):
        # q_t(x, t) + d q_xxxx(x, t) = 0
        # q(x, 0) = amplitude * f(2 pi lambda x) + offset, where f is sin or cos
        # periodic boundary conditions
        # exact solution is then
        # q(x, t) = amplitude * e^{- d (2 pi lambda)^4 t} f(2 pi lambda x) + offset
        if initial_condition is None:
            initial_condition = x_functions.Sine(offset=2.0)
        hyper_diffusion = HyperDiffusion(None, initial_condition, diffusion_constant)

        r = (
            -1.0
            * diffusion_constant
            * np.power(2.0 * np.pi * initial_condition.wavenumber, 4)
        )
        g = copy.deepcopy(initial_condition)
        g.offset = 0.0
        hyper_diffusion.exact_solution = flux_functions.ExponentialFunction(
            g, r, initial_condition.offset
        )
        return hyper_diffusion
def test_linearized_mms_operator_matrix_equivalency():
    g = x_functions.Sine(offset=2.0)
    r = -4.0 * np.power(np.pi, 2)
    exact_solution = flux_functions.ExponentialFunction(g, r)
    t = 0.0
    bc = boundary.Periodic()
    p_func = convection_diffusion.NonlinearDiffusion.linearized_manufactured_solution
    for diffusion_function in diffusion_functions:
        problem = p_func(exact_solution, diffusion_function)
        for basis_class in basis.BASIS_LIST:
            for num_basis_cpts in range(1, 4):
                basis_ = basis_class(num_basis_cpts)
                mesh_ = mesh.Mesh1DUniform(0.0, 1.0, 20)
                dg_solution = basis_.project(problem.initial_condition, mesh_)
                L = problem.ldg_operator(dg_solution, t, bc, bc)
                tuple_ = problem.ldg_matrix(dg_solution, t, bc, bc)
                matrix = tuple_[0]
                vector = tuple_[1]
                dg_vector = dg_solution.to_vector()
                error = np.linalg.norm(L.to_vector() -
                                       np.matmul(matrix, dg_vector) - vector)
                assert error < tolerance
def test_matrix_operator_equivalency():
    t = 0.0
    for bc in [boundary.Periodic(), boundary.Extrapolation()]:
        for nonlinear_diffusion in test_problems:
            nonlinear_diffusion.initial_condition = x_functions.Sine(
                offset=2.0)
            for num_basis_cpts in range(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_diffusion.initial_condition, mesh_)
                    L = nonlinear_diffusion.ldg_operator(
                        dg_solution, t, bc, bc)
                    dg_vector = dg_solution.to_vector()
                    tuple_ = nonlinear_diffusion.ldg_matrix(
                        dg_solution, t, bc, bc)
                    matrix = tuple_[0]
                    vector = tuple_[1]
                    error = np.linalg.norm(L.to_vector() -
                                           np.matmul(matrix, dg_vector) -
                                           vector)
                    assert error <= tolerance
Example #16
0
def test_dg_operator():
    # test that dg_operator converges to exact_time_derivative in smooth case
    initial_condition = x_functions.Sine(offset=2.0)
    max_wavespeed = 3.0
    problem = smooth_example.SmoothExample(initial_condition, max_wavespeed)

    riemann_solver = riemann_solvers.LocalLaxFriedrichs(problem)
    boundary_condition = boundary.Periodic()

    x_left = 0.0
    x_right = 1.0

    exact_time_derivative = burgers.ExactTimeDerivative(
        problem.initial_condition)
    exact_time_derivative_initial = x_functions.FrozenT(
        exact_time_derivative, 0.0)

    for basis_class in basis.BASIS_LIST:
        for num_basis_cpts in range(1, 5):
            basis_ = basis_class(num_basis_cpts)
            error_list = []
            for num_elems in [40, 80]:
                mesh_ = mesh.Mesh1DUniform(x_left, x_right, num_elems)
                dg_solution = basis_.project(problem.initial_condition, mesh_)
                explicit_operator = problem.app_.get_explicit_operator(
                    riemann_solver, boundary_condition)

                dg_time_derivative = explicit_operator(0.0, dg_solution)
                error = math_utils.compute_error(
                    dg_time_derivative, exact_time_derivative_initial)
                error_list.append(error)
            order = test_utils.convergence_order(error_list)
            if num_basis_cpts > 1:
                assert order >= num_basis_cpts - 1
            else:
                assert order >= 1
    def __init__(self,
                 wavespeed=1.0,
                 initial_condition=None,
                 source_function=None):
        self.wavespeed = wavespeed
        if initial_condition is None:
            initial_condition = x_functions.Sine()

        app = advection.Advection(wavespeed, source_function)
        max_wavespeed = wavespeed
        exact_solution = advection.ExactSolution(initial_condition, wavespeed)
        exact_operator = advection.ExactOperator(exact_solution, wavespeed,
                                                 source_function)
        exact_time_derivative = advection.ExactTimeDerivative(
            exact_solution, wavespeed, source_function)

        super().__init__(
            app,
            initial_condition,
            max_wavespeed,
            exact_solution,
            exact_operator,
            exact_time_derivative,
        )
from apps.onedimensional.advection import advection
from pydogpack.utils import x_functions
from pydogpack import main
from pydogpack.visualize import plot


class SmoothSystemExample(problem.Problem):
    def __init__(self, wavespeed=1.0, initial_condition=None, source_function=None):
        self.wavespeed = wavespeed
        if initial_condition is None:
            self.initial_condition = x_functions.Sine()
        else:
            self.initial_condition = initial_condition

        app = advection.Advection(wavespeed, source_function)
        max_wavespeed = wavespeed
        exact_solution = advection.ExactSolution(initial_condition, wavespeed)

        super().__init__(
            app, initial_condition, max_wavespeed, exact_solution
        )


if __name__ == "__main__":
    wavespeed = 1.0
    initial_condition = x_functions.ComposedVector(
        [x_functions.Sine(), x_functions.Cosine()]
    )
    problem = SmoothSystemExample(wavespeed, initial_condition)
    final_solution = main.run(problem)
Example #19
0
from apps.onedimensional.advection.smoothscalarexample import smooth_scalar_example as asse
from apps.onedimensional.burgers import burgers
from apps.onedimensional.linearsystem.smoothexample import smooth_example as lsse
from pydogpack.riemannsolvers import riemann_solvers
from pydogpack.utils import x_functions

import numpy as np

tolerance = 1e-12

advection_problem = asse.SmoothScalarExample(1.0, x_functions.Sine())
# burgers_problem = None
ic = x_functions.ComposedVector([x_functions.Sine(), x_functions.Cosine()])
linear_system_problem = lsse.SmoothExample(np.array([[1, 5], [5, 1]]), ic)
# shallow_water_problem = None
problem_list = [
    advection_problem,
    # burgers_problem,
    linear_system_problem,
    # shallow_water_problem,
]
default_q_list = [
    0.5,
    # 0.5,
    np.array([0.5, 0.5]),
    # np.array([0.5, 0.5]),
]


def sample_problems(riemann_solver_class, do_check_monotonicity=True):
    for i in range(len(problem_list)):
Example #20
0
from apps import app
from apps.onedimensional.convectiondiffusion import convection_diffusion
from apps.onedimensional.convectionhyperdiffusion import ldg
from pydogpack.utils import dg_utils
from pydogpack.utils import flux_functions
from pydogpack.utils import x_functions
from pydogpack.utils import xt_functions

from inspect import signature
import numpy as np
import copy

# solution should be positive so initial condition should default to positive
default_initial_condition = x_functions.Sine(offset=2.0)


# represents q_t + (f(q, x))_x = -(g(q) q_xxx)_x + s(x)
# solution needs to be positive to avoid backward diffusion
class ConvectionHyperDiffusion(app.App):
    def __init__(
        self,
        flux_function=None,
        diffusion_function=None,
        source_function=None,
        initial_condition=default_initial_condition,
        max_wavespeed=1.0,
    ):
        # default to linear hyper diffusion, with diffusion constant 1
        if diffusion_function is None:
            self.diffusion_function = flux_functions.Polynomial(degree=0)
        else:
Example #21
0
            exact_solution,
            exact_operator,
            exact_time_derivative,
        )


class ExactSolution(xt_functions.XTFunction):
    # TODO: Add source function
    def __init__(self, initial_condition):
        self.initial_condition = initial_condition

    def function(self, x, t):
        # TODO: does this work if x is array
        # solve characteristics
        # find xi that satisfies x = initial_condition(xi) * t + xi
        # then exact solution is u(x, t) = initial_condition(xi)
        def xi_function(xi):
            return self.initial_condition(xi) * t + xi - x

        # if exact solution has shocked, then newton will throw error
        # TODO: could catch exception
        xi = optimize.newton(xi_function, x)
        return self.initial_condition(xi)


if __name__ == "__main__":
    initial_condition = x_functions.Sine()
    max_wavespeed = 1.0
    problem = SmoothExample(initial_condition, max_wavespeed)
    final_solution = main.run(problem)
def test_sine():
    sine = x_functions.Sine()
    check_x_function(sine)