def test_strang_splitting(plot_solution=False): from leap.rk import LSRK4MethodBuilder method1 = LSRK4MethodBuilder("y", rhs_func_name="<func>y1") method2 = LSRK4MethodBuilder("y", rhs_func_name="<func>y2") code1 = method1.generate() code2 = method2.generate() from leap.transform import strang_splitting code = strang_splitting(code1, code2, "primary") print(code) from utils import python_method_impl_codegen def exact(t): return np.exp(3j*t) from pytools.convergence import EOCRecorder eocrec = EOCRecorder() for dt in 2 ** -np.array(range(4, 7), dtype=np.float64): # noqa pylint:disable=invalid-unary-operand-type interp = python_method_impl_codegen(code, function_map={ "<func>y1": lambda t, y: 1j*y, "<func>y2": lambda t, y: 2j*y, }) interp.set_up(t_start=0, dt_start=dt, context={"y": 1}) final_t = 4 times = [] values = [] for event in interp.run(t_end=final_t): if isinstance(event, interp.StateComputed): values.append(event.state_component) times.append(event.t) assert abs(times[-1] - final_t) / final_t < 0.1 times = np.array(times) # Check that the timestep is preserved. assert np.allclose(np.diff(times), dt) if plot_solution: import matplotlib.pyplot as pt pt.plot(times, values, label="comp") pt.plot(times, exact(times), label="true") pt.show() error = abs(values[-1] - exact(final_t)) eocrec.add_data_point(dt, error) print(eocrec.pretty_print()) orderest = eocrec.estimate_order_of_convergence()[0, 1] assert orderest > 2 * 0.9
def set_up_stepper(self, discr, field_var_name, sym_rhs, num_fields, function_registry=base_function_registry, exec_mapper_factory=ExecutionMapper): dt_method = LSRK4MethodBuilder(component_id=field_var_name) dt_code = dt_method.generate() self.field_var_name = field_var_name self.state_name = f"input_{field_var_name}" # Transcribe the phase. output_vars, results, yielded_states = transcribe_phase( dt_code, field_var_name, num_fields, "primary", sym_rhs) # Build the bound operator for the time integrator. output_t = results[0] output_dt = results[1] output_states = results[2] output_residuals = results[3] assert len(output_states) == num_fields assert len(output_states) == len(output_residuals) flattened_results = flat_obj_array(output_t, output_dt, *output_states) self.bound_op = bind( discr, flattened_results, function_registry=function_registry, exec_mapper_factory=exec_mapper_factory)
def set_up_rk4(field_var_name, dt, fields, rhs, t_start=0): from leap.rk import LSRK4MethodBuilder from dagrt.codegen import PythonCodeGenerator dt_method = LSRK4MethodBuilder(component_id=field_var_name) dt_code = dt_method.generate() dt_stepper_class = PythonCodeGenerator("TimeStep").get_class(dt_code) dt_stepper = dt_stepper_class({"<func>" + dt_method.component_id: rhs}) dt_stepper.set_up(t_start=t_start, dt_start=dt, context={dt_method.component_id: fields}) return dt_stepper
def read_file(rel_path): from os.path import join, abspath, dirname path = join(abspath(dirname(__file__)), rel_path) with open(path, "r") as inf: return inf.read() # {{{ test rk methods @pytest.mark.parametrize(("min_order", "stepper"), [ (2, ODE23MethodBuilder("y", use_high_order=False)), (3, ODE23MethodBuilder("y", use_high_order=True)), (4, ODE45MethodBuilder("y", use_high_order=False)), (5, ODE45MethodBuilder("y", use_high_order=True)), (4, RK4MethodBuilder("y")), (4, LSRK4MethodBuilder("y")), ]) def test_rk_codegen(min_order, stepper, print_code=False): """Test whether Fortran code generation for the Runge-Kutta timestepper works. """ component_id = 'y' rhs_function = '<func>y' from dagrt.function_registry import ( base_function_registry, register_ode_rhs) freg = register_ode_rhs(base_function_registry, component_id, identifier=rhs_function) freg = freg.register_codegen(rhs_function, "fortran", f.CallCode("""
) from leap.rk.imex import KennedyCarpenterIMEXARK4MethodBuilder from mirgecom.steppers import advance_state @pytest.mark.parametrize(("method", "method_order"), [ (ODE23MethodBuilder("y", use_high_order=False), 2), (ODE23MethodBuilder("y", use_high_order=True), 3), (ODE45MethodBuilder("y", use_high_order=False), 4), (ODE45MethodBuilder("y", use_high_order=True), 5), (ForwardEulerMethodBuilder("y"), 1), (MidpointMethodBuilder("y"), 2), (HeunsMethodBuilder("y"), 2), (RK3MethodBuilder("y"), 3), (RK4MethodBuilder("y"), 4), (RK5MethodBuilder("y"), 5), (LSRK4MethodBuilder("y"), 4), (KennedyCarpenterIMEXARK4MethodBuilder( "y", use_implicit=False, explicit_rhs_name="y"), 4), (SSPRK22MethodBuilder("y"), 2), (SSPRK33MethodBuilder("y"), 3), ]) def test_leapgen_integration_order(method, method_order): """Test that time integrators have correct order.""" def exact_soln(t): return np.exp(-t) def rhs(t, y): return -np.exp(-t) from pytools.convergence import EOCRecorder integrator_eoc = EOCRecorder()