def test_evaluate_weak_form(): periodic_bc = boundary.Periodic() t = 0.0 for problem in test_problems: exact_time_derivative = problem.exact_time_derivative initial_time_derivative = x_functions.FrozenT(exact_time_derivative, 0.0) riemann_solver = riemann_solvers.LocalLaxFriedrichs(problem) for basis_class in basis.BASIS_LIST: for num_basis_cpts in range(1, 4): error_list = [] basis_ = basis_class(num_basis_cpts) for num_elems in [20, 40]: mesh_ = mesh.Mesh1DUniform(0.0, 1.0, num_elems) dg_solution = basis_.project(initial_condition, mesh_) result = dg_utils.evaluate_weak_form( dg_solution, t, problem.app_.flux_function, riemann_solver, periodic_bc, problem.app_.nonconservative_function, problem.app_.regularization_path, problem.app_.source_function) error = math_utils.compute_error(result, initial_time_derivative) error_list.append(error) order = utils.convergence_order(error_list) if num_basis_cpts == 1: assert order >= 1 else: assert order >= num_basis_cpts - 1
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_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
def test_advection_finite_time(): def initial_condition(x): return np.sin(2.0 * np.pi * x) advection_ = advection.Advection(initial_condition=initial_condition) riemann_solver = riemann_solvers.LocalLaxFriedrichs( advection_.flux_function, advection_.wavespeed_function ) boundary_condition = boundary.Periodic() time_initial = 0.0 time_final = 0.5 def test_function(dg_solution): explicit_time_stepper = explicit_runge_kutta.get_time_stepper( dg_solution.basis.num_basis_cpts ) cfl = dg_utils.standard_cfls(dg_solution.basis.num_basis_cpts) delta_t = dg_utils.get_delta_t( cfl, advection_.wavespeed, dg_solution.mesh.delta_x ) rhs_function = lambda time, q: dg_utils.dg_weak_formulation( q, advection_.flux_function, riemann_solver, boundary_condition ) return time_stepping.time_step_loop_explicit( dg_solution, time_initial, time_final, delta_t, explicit_time_stepper, rhs_function, ) order_check_function = lambda order, num_basis_cpts: order >= num_basis_cpts utils.basis_convergence( test_function, initial_condition, lambda x: advection_.exact_solution(x, time_final), order_check_function, basis_list=[basis.LegendreBasis1D], basis_cpt_list=[4], )
def from_dict(dict_, problem, fluctuation_solver=None): riemann_solver_class = dict_[riemann_solvers.CLASS_KEY] if riemann_solver_class == riemann_solvers.EXACTLINEAR_STR: return riemann_solvers.ExactLinear(problem) elif riemann_solver_class == riemann_solvers.GODUNOV_STR: return riemann_solvers.Godunov(problem) elif riemann_solver_class == riemann_solvers.ENGQUIST_OSHER_STR: return riemann_solvers.EngquistOsher(problem) elif riemann_solver_class == riemann_solvers.LAX_FRIEDRICHS_STR: return riemann_solvers.LaxFriedrichs(problem) elif riemann_solver_class == riemann_solvers.LOCAL_LAX_FRIEDRICHS_STR: return riemann_solvers.LocalLaxFriedrichs(problem) elif riemann_solver_class == riemann_solvers.CENTRAL_STR: return riemann_solvers.Central(problem) elif riemann_solver_class == riemann_solvers.AVERAGE_STR: return riemann_solvers.Average(problem) elif riemann_solver_class == riemann_solvers.LEFTSIDED_STR: return riemann_solvers.LeftSided(problem) elif riemann_solver_class == riemann_solvers.RIGHTSIDED_STR: return riemann_solvers.RightSided(problem) elif riemann_solver_class == riemann_solvers.UPWIND_STR: return riemann_solvers.Upwind(problem) elif riemann_solver_class == riemann_solvers.ROE_STR: return riemann_solvers.Roe(problem) elif riemann_solver_class == riemann_solvers.HLL_STR: return riemann_solvers.HLL(problem) elif riemann_solver_class == riemann_solvers.HLLE_STR: return riemann_solvers.HLLE(problem) elif riemann_solver_class == riemann_solvers.LEFT_FLUCTUATION_STR: return riemann_solvers.LeftFluctuation(problem, fluctuation_solver) elif riemann_solver_class == riemann_solvers.RIGHT_FLUCTUATION_STR: return riemann_solvers.RightFluctuation(problem, fluctuation_solver) elif riemann_solver_class == riemann_solvers.CENTERED_FLUCTUATION_STR: return riemann_solvers.CenteredFluctuation(problem, fluctuation_solver) elif riemann_solver_class == riemann_solvers.NONCONSERVATIVEHLLE_STR: return riemann_solvers.NonconservativeHLLE(problem) elif riemann_solver_class == utils.LEFT_SIDED_DIFFUSION_STR: return utils.LeftSidedDiffusionRiemannSolver(problem) elif riemann_solver_class == utils.RIGHT_SIDED_DIFFUSION_STR: return utils.RightSidedDiffusionRiemannSolver(problem) else: raise riemann_solvers.errors.InvalidParameter( riemann_solvers.CLASS_KEY, riemann_solver_class)
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
def riemann_solver_factory(problem, riemann_solver_class, fluctuation_solver=None): if riemann_solver_class is riemann_solvers.ExactLinear: return riemann_solvers.ExactLinear(problem) elif riemann_solver_class is riemann_solvers.Godunov: return riemann_solvers.Godunov(problem) elif riemann_solver_class is riemann_solvers.EngquistOsher: return riemann_solvers.EngquistOsher(problem) elif riemann_solver_class is riemann_solvers.LaxFriedrichs: return riemann_solvers.LaxFriedrichs(problem) elif riemann_solver_class is riemann_solvers.LocalLaxFriedrichs: return riemann_solvers.LocalLaxFriedrichs(problem) elif riemann_solver_class is riemann_solvers.Central: return riemann_solvers.Central(problem) elif riemann_solver_class is riemann_solvers.Average: return riemann_solvers.Average(problem) elif riemann_solver_class is riemann_solvers.LeftSided: return riemann_solvers.LeftSided(problem) elif riemann_solver_class is riemann_solvers.RightSided: return riemann_solvers.RightSided(problem) elif riemann_solver_class is riemann_solvers.Upwind: return riemann_solvers.Upwind(problem) elif riemann_solver_class is riemann_solvers.Roe: return riemann_solvers.Roe(problem) elif riemann_solver_class is riemann_solvers.HLL: return riemann_solvers.HLL(problem) elif riemann_solver_class is riemann_solvers.HLLE: return riemann_solvers.HLLE(problem) elif riemann_solver_class is riemann_solvers.LeftFluctuation: return riemann_solvers.LeftFluctuation(problem, fluctuation_solver) elif riemann_solver_class is riemann_solvers.RightFluctuation: return riemann_solvers.RightFluctuation(problem, fluctuation_solver) elif riemann_solver_class is riemann_solvers.CenteredFluctuation: return riemann_solvers.CenteredFluctuation(problem, fluctuation_solver) elif riemann_solver_class is riemann_solvers.NonconservativeHLLE: return riemann_solvers.NonconservativeHLLE(problem) elif riemann_solver_class is utils.LeftSidedDiffusionRiemannSolver: return utils.LeftSidedDiffusionRiemannSolver(problem) elif riemann_solver_class is utils.RightSidedDiffusionRiemannSolver: return utils.RightSidedDiffusionRiemannSolver(problem) raise Exception("riemann_solver_class is not accepted")
def get_dg_rhs_function( flux_function, source_function=None, riemann_solver=None, boundary_condition=None, nonconservative_function=None, regularization_path=None, is_weak=True, ): # for PDE q_t + f(q, x, t)_x = s(q, x, t) # or q_t = -f(q, x, t)_x + s(q, x, t) # get DG discretization of F(t, q) = -f(q, x, t)_x + s(q, x, t) # return function F(t, q) - used in time_stepping methods if riemann_solver is None: riemann_solver = riemann_solvers.LocalLaxFriedrichs(flux_function) if boundary_condition is None: boundary_condition = boundary.Periodic() if is_weak: def rhs_function(t, q): return evaluate_weak_form( q, t, flux_function, riemann_solver, boundary_condition, nonconservative_function, regularization_path, source_function, ) else: def rhs_function(t, q): return evaluate_strong_form(q, t, flux_function, riemann_solver, boundary_condition, source_function) return rhs_function
def test_advection_one_time_step(): def initial_condition(x): return np.sin(2.0 * np.pi * x) advection_ = advection.Advection(initial_condition=initial_condition) riemann_solver = riemann_solvers.LocalLaxFriedrichs( advection_.flux_function, advection_.wavespeed_function ) explicit_time_stepper = explicit_runge_kutta.ForwardEuler() boundary_condition = boundary.Periodic() cfl = 1.0 for basis_class in basis.BASIS_LIST: basis_ = basis_class(1) error_list = [] for num_elems in [20, 40]: mesh_ = mesh.Mesh1DUniform(0.0, 1.0, num_elems) dg_solution = basis_.project(advection_.initial_condition, mesh_) delta_t = dg_utils.get_delta_t(cfl, advection_.wavespeed, mesh_.delta_x) time_initial = 0.0 time_final = delta_t rhs_function = lambda time, q: dg_utils.dg_weak_formulation( q, advection_.flux_function, riemann_solver, boundary_condition ) final_solution = time_stepping.time_step_loop_explicit( dg_solution, time_initial, time_final, delta_t, explicit_time_stepper, rhs_function, ) error = math_utils.compute_error( final_solution, lambda x: advection_.exact_solution(x, time_final) ) error_list.append(error) order = utils.convergence_order(error_list) assert order >= 1
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])
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