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
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_class = convection_hyper_diffusion.NonlinearHyperDiffusion p_func = p_class.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, bc, bc) sine_matrix = tuple_[0] sine_vector = tuple_[1] tuple_ = problem.ldg_matrix(cosine_dg, t_initial, bc, bc, 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 check_solution_operations_1d(basis_, tol2=tolerance): mesh_ = mesh.Mesh1DUniform(-1.0, 1.0, 100) # checking not inplace operations also checks inplace operations # as not inplace operators refer to inplace operations cos = x_functions.Cosine() sin = x_functions.Sine() cos_sol = basis_.project(cos, mesh_) sin_sol = basis_.project(sin, mesh_) # addition def func(x): return cos(x) + sin(x) new_sol = basis_.do_solution_operation(cos_sol, sin_sol, operator.iadd) projected_sol = basis_.project(func, mesh_) error = np.linalg.norm(new_sol.coeffs - projected_sol.coeffs) assert error <= tolerance # subtraction def func(x): return cos(x) - sin(x) new_sol = basis_.do_solution_operation(cos_sol, sin_sol, operator.isub) projected_sol = basis_.project(func, mesh_) error = np.linalg.norm(new_sol.coeffs - projected_sol.coeffs) assert error <= tolerance # multiplication, division, and power won't be exact for modal bases # multiplication def func(x): return cos(x) * sin(x) new_sol = basis_.do_solution_operation(cos_sol, sin_sol, operator.imul) projected_sol = basis_.project(func, mesh_) error = np.linalg.norm(new_sol.coeffs - projected_sol.coeffs) assert error <= tol2 # division def func(x): return cos(x) / (sin(x) + 2) sin_p2_sol = basis_.do_constant_operation(sin_sol, 2, operator.iadd) new_sol = basis_.do_solution_operation(cos_sol, sin_p2_sol, operator.itruediv) projected_sol = basis_.project(func, mesh_) error = np.linalg.norm(new_sol.coeffs - projected_sol.coeffs) assert error <= tol2 # power def func(x): return (cos(x) + 2)**(sin(x) + 2) cos_p2_sol = basis_.do_constant_operation(cos_sol, 2, operator.iadd) new_sol = basis_.do_solution_operation(cos_p2_sol, sin_p2_sol, operator.ipow) projected_sol = basis_.project(func, mesh_) error = np.linalg.norm(new_sol.coeffs - projected_sol.coeffs) assert error <= tol2
def __init__( self, amplitude=1.0, wavenumber=1.0, offset=0.0, phase=0.0, wavespeed=1.0 ): self.amplitude = amplitude self.wavenumber = wavenumber self.offset = offset self.phase = phase g = x_functions.Cosine(amplitude, wavenumber, offset, phase) AdvectingFunction.__init__(self, g, wavespeed)
def test_solution_operations_inplace(): # 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.copy() new_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.copy() new_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.copy() new_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.copy() new_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.copy() new_sol **= sinp2_sol.copy() projected_sol = basis_.project(func, mesh_) error = (new_sol - projected_sol).norm() assert error <= tolerance_2
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])
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)
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)):
def test_cosine(): cosine = x_functions.Cosine() check_x_function(cosine)