Exemple #1
0
    def linearized_manufactured_solution(
        exact_solution, flux_function=None, diffusion_function=None, max_wavespeed=1.0
    ):
        if flux_function is None:
            flux_function = flux_functions.Identity()
        if diffusion_function is None:
            diffusion_function = flux_functions.Polynomial(degree=0)

        source_function = ExactOperator(
            exact_solution, flux_function, diffusion_function, flux_functions.Zero()
        )
        initial_condition = x_functions.FrozenT(exact_solution, 0.0)

        linearized_diffusion_function = flux_functions.LinearizedAboutQ(
            diffusion_function, exact_solution
        )

        problem = ConvectionHyperDiffusion(
            flux_function,
            linearized_diffusion_function,
            source_function,
            initial_condition,
            max_wavespeed,
        )
        problem.exact_solution = exact_solution
        return problem
    def linearized_manufactured_solution(
        exact_solution, flux_function=None, diffusion_function=None, max_wavespeed=1.0
    ):
        if flux_function is None:
            flux_function = flux_functions.Identity()
        if diffusion_function is None:
            diffusion_function = flux_functions.Polynomial(degree=0)

        # source_function could be computed with original diffusion function
        # or with linearized diffusion function
        # ? Would that make a difference?
        source_function = ExactOperator(
            exact_solution, flux_function, diffusion_function, flux_functions.Zero()
        )
        initial_condition = x_functions.FrozenT(exact_solution, 0.0)

        linearized_diffusion_function = xt_functions.LinearizedAboutQ(
            diffusion_function, exact_solution
        )

        problem = ConvectionDiffusion(
            flux_function,
            linearized_diffusion_function,
            source_function,
            initial_condition,
            max_wavespeed,
        )
        problem.exact_solution = exact_solution

        return problem
    def linearized_manufactured_solution(exact_solution, diffusion_function=None):
        if diffusion_function is None:
            diffusion_function = flux_functions.Polynomial(degree=0)

        # source_function could be computed with original diffusion function
        # or with linearized diffusion function
        # ? Would that make a difference?
        source_function = ExactOperator(
            exact_solution,
            flux_functions.Zero(),
            diffusion_function,
            flux_functions.Zero(),
        )
        initial_condition = x_functions.FrozenT(exact_solution, 0.0)

        # linearize diffusion function
        new_diffusion_function = xt_functions.LinearizedAboutQ(
            diffusion_function, exact_solution
        )

        problem = NonlinearDiffusion(
            new_diffusion_function, source_function, initial_condition
        )
        problem.exact_solution = exact_solution

        return problem
Exemple #4
0
    def __init__(
        self,
        source_function=None,
        initial_condition=None,
        max_wavespeed=None,
        moving_reference_frame=False,
    ):
        if initial_condition is None:
            initial_condition = x_functions.Sine(amplitude=0.1, offset=0.15)

        # wavespeed function = 2 q - 3 q^2
        # maximized at q = 1/3, the wavespeed is also 1/3 at this point
        if max_wavespeed is None:
            max_wavespeed = 1.0 / 3.0

        if moving_reference_frame:
            flux_function = flux_functions.Polynomial(
                [0.0, -1.0 * max_wavespeed, 1.0, -1.0]
            )
        else:
            flux_function = default_flux_function

        convection_hyper_diffusion.ConvectionHyperDiffusion.__init__(
            self,
            flux_function,
            default_diffusion_function,
            source_function,
            initial_condition,
            max_wavespeed,
        )
Exemple #5
0
    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:
            self.diffusion_function = diffusion_function
        self.is_diffusive = not isinstance(self.diffusion_function, flux_functions.Zero)

        self.is_linear_hyperdiffusion = (
            isinstance(diffusion_function, flux_functions.Polynomial)
            and diffusion_function.degree == 0
        )
        if self.is_linear_hyperdiffusion:
            self.diffusion_constant = diffusion_function.coeffs[0]

        self.is_convective = not isinstance(flux_function, flux_functions.Zero)

        app.App.__init__(
            self, flux_function, source_function
        )
Exemple #6
0
    def __init__(
        self,
        wavespeed=1.0,
        source_function=None,
    ):
        self.wavespeed = wavespeed
        flux_function = flux_functions.Polynomial([0.0, self.wavespeed])

        app.App.__init__(self, flux_function, source_function)
Exemple #7
0
def test_compute_quadrature_matrix():
    squared = flux_functions.Polynomial(degree=2)
    cubed = flux_functions.Polynomial(degree=3)
    initial_condition = functions.Sine()
    t = 0.0
    x_left = 0.0
    x_right = 1.0
    for f in [squared, cubed]:
        for basis_class in basis.BASIS_LIST:
            for num_basis_cpts in range(1, 6):
                error_list = []
                basis_ = basis_class(num_basis_cpts)
                for num_elems in [10, 20]:
                    mesh_ = mesh.Mesh1DUniform(x_left, x_right, num_elems)
                    dg_solution = basis_.project(initial_condition, mesh_)
                    quadrature_matrix = ldg_utils.compute_quadrature_matrix(
                        dg_solution, t, f)
                    result = solution.DGSolution(None, basis_, mesh_)
                    direct_quadrature = solution.DGSolution(
                        None, basis_, mesh_)
                    for i in range(mesh_.num_elems):
                        # compute value as B_i Q_i
                        result[i] = np.matmul(quadrature_matrix[i],
                                              dg_solution[i])
                        # also compute quadrature directly
                        for l in range(basis_.num_basis_cpts):
                            quadrature_function = (lambda xi: f(
                                initial_condition(
                                    mesh_.transform_to_mesh(xi, i)),
                                xi,
                            ) * initial_condition(
                                mesh_.transform_to_mesh(xi, i)) * basis_.
                                                   derivative(xi, l))
                            direct_quadrature[i, l] = math_utils.quadrature(
                                quadrature_function, -1.0, 1.0)
                        # need to multiply by mass inverse
                        direct_quadrature[i] = np.matmul(
                            basis_.mass_matrix_inverse, direct_quadrature[i])
                    error = (result - direct_quadrature).norm()
                    error_list.append(error)
                if error_list[-1] != 0.0:
                    order = utils.convergence_order(error_list)
                    assert order >= (num_basis_cpts - 1)
    def __init__(
        self, source_function=None, initial_condition=None, diffusion_constant=1.0
    ):
        # diffusion function is f(q, x, t) = d
        self.diffusion_constant = diffusion_constant
        diffusion_function = flux_functions.Polynomial([diffusion_constant])

        NonlinearDiffusion.__init__(
            self, diffusion_function, source_function, initial_condition
        )
Exemple #9
0
def test_compute_quadrature_matrix_one():
    # quadrature_matrix should be same as M^{-1} S^T
    t = 0.0
    f = flux_functions.Polynomial(degree=0)
    initial_condition = functions.Sine()
    for basis_class in basis.BASIS_LIST:
        for num_basis_cpts in range(1, 6):
            basis_ = basis_class(num_basis_cpts)
            mesh_ = mesh.Mesh1DUniform(0.0, 1.0, 10)
            dg_solution = basis_.project(initial_condition, mesh_)
            quadrature_matrix = ldg_utils.compute_quadrature_matrix(
                dg_solution, t, f)
            error = quadrature_matrix - basis_.mass_inverse_stiffness_transpose
            assert np.linalg.norm(error) <= tolerance
 def manufactured_solution(exact_solution, diffusion_function=None):
     if diffusion_function is None:
         diffusion_function = flux_functions.Polynomial(degree=0)
     source_function = ExactOperator(
         exact_solution,
         flux_functions.Zero(),
         diffusion_function,
         flux_functions.Zero(),
     )
     initial_condition = x_functions.FrozenT(exact_solution, 0.0)
     problem = NonlinearDiffusion(
         diffusion_function, source_function, initial_condition
     )
     problem.exact_solution = exact_solution
     return problem
Exemple #11
0
def test_linearized_about_q():
    original_flux_function = flux_functions.Polynomial(degree=3)
    q = xt_functions.AdvectingSine()
    xt_function = xt_functions.LinearizedAboutQ(original_flux_function, q)
    utils.check_to_from_dict(xt_function, xt_functions)

    x = 0.5
    t = 0.1
    assert xt_function(q(x, t), x, t) is not None
    assert xt_function(x, t) is not None
    assert xt_function(x, t) == xt_function(q(x, t), x, t)

    for x in range(10):
        for t in range(10):
            assert xt_function(x, t) == original_flux_function(q(x, t), x, t)
    def __init__(
        self,
        flux_function=None,
        diffusion_function=None,
        source_function=None,
        initial_condition=None,
        max_wavespeed=1.0,
    ):
        # default to linear diffusion with diffusion constant 1
        if diffusion_function is None:
            self.diffusion_function = flux_functions.Polynomial(degree=0)
        else:
            self.diffusion_function = diffusion_function

        app.App.__init__(
            self, flux_function, source_function,
        )
Exemple #13
0
    def __init__(
        self,
        q,
        flux_function=None,
        diffusion_function=None,
        source_function=None,
        default_t=None,
    ):
        self.q = q
        if flux_function is None:
            self.flux_function = flux_functions.Zero
        else:
            self.flux_function = flux_function

        if diffusion_function is None:
            self.diffusion_function = flux_functions.Polynomial(degree=0)
        else:
            self.diffusion_function = diffusion_function

        if source_function is None:
            self.source_function = flux_functions.Zero()
        else:
            self.source_function = source_function
        xt_functions.XTFunction.__init__(self)
Exemple #14
0
def get_defaults(
    dg_solution,
    t,
    diffusion_function=None,
    source_function=None,
    q_boundary_condition=None,
    r_boundary_condition=None,
    q_numerical_flux=None,
    r_numerical_flux=None,
    quadrature_matrix_function=None,
):
    basis_ = dg_solution.basis
    mesh_ = dg_solution.mesh
    Q = dg_solution

    # default to linear diffusion with diffusion constant 1
    if diffusion_function is None:
        diffusion_function = flux_functions.Polynomial(degree=0)

    # if is linear diffusion then diffusion_function will be constant
    is_linear = (
        isinstance(diffusion_function, flux_functions.Polynomial)
        and diffusion_function.degree == 0
    )
    if is_linear:
        diffusion_constant = diffusion_function.coeffs[0]

    # default to 0 source
    if source_function is None:
        source_function = flux_functions.Zero()

    # default boundary conditions
    if q_boundary_condition is None:
        q_boundary_condition = boundary.Periodic()
    if r_boundary_condition is None:
        r_boundary_condition = boundary.Periodic()

    # Default numerical fluxes
    if q_numerical_flux is None:
        q_numerical_flux = riemann_solvers.RightSided(
            flux_functions.Polynomial([0.0, -1.0])
        )
    if r_numerical_flux is None:
        if is_linear:
            r_numerical_flux = riemann_solvers.LeftSided(
                flux_functions.Polynomial([0.0, -1.0 * diffusion_constant])
            )
        else:

            def wavespeed_function(x):
                # need to make sure q is evaluated on left side of interfaces
                if mesh_.is_interface(x):
                    vertex_index = mesh_.get_vertex_index(x)
                    left_elem_index = mesh_.faces_to_elems[vertex_index, 0]
                    # if on left boundary
                    if left_elem_index == -1:
                        if isinstance(q_boundary_condition, boundary.Periodic):
                            left_elem_index = mesh_.get_rightmost_elem_index()
                            q = Q(mesh_.x_right, left_elem_index)
                        else:
                            left_elem_index = mesh_.get_leftmost_elem_index()
                            q = Q(x, left_elem_index)
                    else:
                        q = Q(x, left_elem_index)
                else:
                    q = Q(x)

                return -1.0 * diffusion_function(q, x, t)

            r_numerical_flux = riemann_solvers.LeftSided(
                flux_functions.VariableAdvection(wavespeed_function)
            )

    # default quadrature function is to directly compute using dg_solution
    # and diffusion_function
    if quadrature_matrix_function is None:
        # if diffusion_function is a constant,
        # then quadrature_matrix_function will be constant,  -e M^{-1}S^T
        # where e is diffusion constant
        if is_linear:
            quadrature_matrix_function = dg_utils.get_quadrature_matrix_function_matrix(
                -1.0 * diffusion_constant * basis_.mass_inverse_stiffness_transpose
            )
        else:
            # M^{-1} \dintt{D_i}{-f(Q, x, t) R \Phi_x}{x} = B_i R_i
            quadrature_matrix_function = ldg_utils.get_quadrature_matrix_function(
                dg_solution, t, lambda q, x, t: -1.0 * diffusion_function(q, x, t)
            )

    return (
        diffusion_function,
        source_function,
        q_boundary_condition,
        r_boundary_condition,
        q_numerical_flux,
        r_numerical_flux,
        quadrature_matrix_function,
    )
Exemple #15
0
from pydogpack.mesh import mesh
from pydogpack.mesh import boundary
from pydogpack.localdiscontinuousgalerkin import utils as ldg_utils
from pydogpack.solution import solution
from pydogpack.tests.utils import utils
from pydogpack.timestepping import time_stepping
from pydogpack.timestepping import implicit_runge_kutta
from pydogpack.utils import flux_functions
from pydogpack.utils import math_utils
from pydogpack.utils import x_functions
from pydogpack.visualize import plot

import numpy as np

identity = flux_functions.Identity()
squared = flux_functions.Polynomial(degree=2)
diffusion_functions = [identity, squared]
# (q q_x)_x
hyper_diffusion_identity = convection_hyper_diffusion.NonlinearHyperDiffusion(
    identity)
# (q^2 q_x)_x
hyper_diffusion_squared = convection_hyper_diffusion.NonlinearHyperDiffusion(
    squared)
test_problems = [hyper_diffusion_identity, hyper_diffusion_squared]
tolerance = 1e-5


def test_ldg_constant():
    # LDG of one should be zero
    t = 0.0
    for nonlinear_hyper_diffusion in test_problems:
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
Exemple #17
0
    def __init__(self, q, source_function=None):
        flux_function = flux_functions.Polynomial([0.0, 0.0, 0.5])

        app.ExactTimeDerivative.__init__(self, q, flux_function, source_function)
Exemple #18
0
    def __init__(self, source_function=None):
        flux_function = flux_functions.Polynomial([0.0, 0.0, 0.5])

        super().__init__(
            flux_function, source_function,
        )
Exemple #19
0
    def __init__(self, q, wavespeed=1.0, source_function=None):
        self.wavespeed = wavespeed
        flux_function = flux_functions.Polynomial([0.0, self.wavespeed])

        app.ExactOperator.__init__(self, q, flux_function, source_function)
Exemple #20
0
    def __init__(self, q, source_function=None):
        flux_function = flux_functions.Polynomial([0.0, 0.0, 0.5])

        app.ExactOperator.__init__(self, q, flux_function, source_function)
Exemple #21
0
    def __init__(self, q, wavespeed=1.0, source_function=None):
        self.wavespeed = wavespeed
        flux_function = flux_functions.Polynomial([0.0, self.wavespeed])

        app.ExactTimeDerivative.__init__(self, q, flux_function,
                                         source_function)
Exemple #22
0
from pydogpack.utils import flux_functions
from pydogpack.utils import x_functions
from apps.onedimensional.convectionhyperdiffusion import convection_hyper_diffusion
from apps.onedimensional.convectiondiffusion import convection_diffusion
from apps.onedimensional.thinfilm import ldg

import numpy as np

default_flux_function = flux_functions.Polynomial([0.0, 0.0, 1.0, -1.0])
default_diffusion_function = flux_functions.Polynomial(degree=3)


# represents q_t + (q^2 - q^3)_x = -(q^3 q_xxx)_x + s(x)
class ThinFilm(convection_hyper_diffusion.ConvectionHyperDiffusion):
    def __init__(
        self,
        source_function=None,
        initial_condition=None,
        max_wavespeed=None,
        moving_reference_frame=False,
    ):
        if initial_condition is None:
            initial_condition = x_functions.Sine(amplitude=0.1, offset=0.15)

        # wavespeed function = 2 q - 3 q^2
        # maximized at q = 1/3, the wavespeed is also 1/3 at this point
        if max_wavespeed is None:
            max_wavespeed = 1.0 / 3.0

        if moving_reference_frame:
            flux_function = flux_functions.Polynomial(
from pydogpack.utils import xt_functions
from pydogpack.utils import flux_functions
from pydogpack.basis import basis
from pydogpack.mesh import mesh
from pydogpack.mesh import boundary
from apps.onedimensional.convectiondiffusion import convection_diffusion

import numpy as np
import yaml

if __name__ == "__main__":
    exact_solution = xt_functions.AdvectingSine(amplitude=0.1, offset=0.15)
    diffusion_function = flux_functions.Polynomial(degree=3)
    problem = convection_diffusion.NonlinearDiffusion.manufactured_solution(
        exact_solution, diffusion_function)
    t = 0.0
    bc = boundary.Periodic()
    n = 10
    dict_ = dict()
    for bc in [boundary.Periodic(), boundary.Extrapolation()]:
        dict_[str(bc)] = dict()
        dict_bc = dict_[str(bc)]
        for basis_class in basis.BASIS_LIST:
            dict_bc[basis_class.string] = dict()
            dict_basis = dict_bc[basis_class.string]
            for num_basis_cpts in range(1, 4):
                dict_basis[num_basis_cpts] = dict()
                dict_cpt = dict_basis[num_basis_cpts]
                basis_ = basis_class(num_basis_cpts)
                for num_elems in range(10, 90, 10):
                    mesh_ = mesh.Mesh1DUniform(0.0, 1.0, num_elems)