def check_simple_convergence(method, method_impl, expected_order, problem=DefaultProblem(), dts=_default_dts, show_dag=False, plot_solution=False): component_id = method.component_id code = method.generate() print(code) if show_dag: from dagrt.language import show_dependency_graph show_dependency_graph(code) from pytools.convergence import EOCRecorder eocrec = EOCRecorder() for dt in dts: t = problem.t_start y = problem.initial() final_t = problem.t_end interp = method_impl(code, function_map={ "<func>" + component_id: problem, }) interp.set_up(t_start=t, dt_start=dt, context={component_id: y}) times = [] values = [] for event in interp.run(t_end=final_t): if isinstance(event, interp.StateComputed): assert event.component_id == component_id values.append(event.state_component[0]) times.append(event.t) assert abs(times[-1] - final_t) / final_t < 0.1 times = np.array(times) if plot_solution: import matplotlib.pyplot as pt pt.plot(times, values, label="comp") pt.plot(times, problem.exact(times), label="true") pt.show() error = abs(values[-1] - problem.exact(final_t)) eocrec.add_data_point(dt, error) print("------------------------------------------------------") print("%s: expected order %d" % (method.__class__.__name__, expected_order)) print("------------------------------------------------------") print(eocrec.pretty_print()) orderest = eocrec.estimate_order_of_convergence()[0, 1] assert orderest > expected_order * 0.9
def euler(component_id, show_dag): from leap.multistep import AdamsBashforthMethod method = AdamsBashforthMethod(component_id, 1, static_dt=True) code = method.generate() if show_dag: from dagrt.language import show_dependency_graph show_dependency_graph(code) return code
def test_dot(order=3, step_ratio=3, method_name="F", show=False): method = TwoRateAdamsBashforthMethod(method_name, order=order, step_ratio=step_ratio, hist_consistency_threshold=1e-8) code = method.generate() from dagrt.language import get_dot_dependency_graph print(get_dot_dependency_graph(code)) if show: from dagrt.language import show_dependency_graph show_dependency_graph(code)
def show_dag(self, dt=2**(-6)): from dagrt.language import show_dependency_graph show_dependency_graph(self.get_code(dt))
def test_step_matrix(method, show_matrix=True, show_dag=False): component_id = 'y' code = method.generate() if show_dag: from dagrt.language import show_dependency_graph show_dependency_graph(code) from dagrt.exec_numpy import NumpyInterpreter from leap.step_matrix import StepMatrixFinder from pymbolic import var # {{{ build matrix def rhs_sym(t, y): return var("lambda") * y finder = StepMatrixFinder(code, function_map={"<func>" + component_id: rhs_sym}) mat = finder.get_phase_step_matrix("primary") if show_matrix: print('Variables: %s' % finder.variables) from pytools import indices_in_shape for i in indices_in_shape(mat.shape): print(i, mat[i]) # }}} dt = 0.1 lambda_ = -0.4 def rhs(t, y): return lambda_ * y interp = NumpyInterpreter(code, function_map={"<func>" + component_id: rhs}) interp.set_up(t_start=0, dt_start=dt, context={component_id: 15}) assert interp.next_phase == "initial" for event in interp.run_single_step(): pass assert interp.next_phase == "primary" start_values = np.array([interp.context[v] for v in finder.variables]) for event in interp.run_single_step(): pass assert interp.next_phase == "primary" stop_values = np.array([interp.context[v] for v in finder.variables]) from dagrt.expression import EvaluationMapper concrete_mat = EvaluationMapper({ "lambda": lambda_, "<dt>": dt, }, {})(mat) stop_values_from_mat = concrete_mat.dot(start_values) rel_err = ( la.norm(stop_values - stop_values_from_mat) / # noqa: W504 la.norm(stop_values)) assert rel_err < 1e-12
def test_im_euler_accuracy(python_method_impl, show_dag=False, plot_solution=False): component_id = "y" from implicit_euler import ImplicitEulerMethod method = ImplicitEulerMethod(component_id) code = method.generate(solver_hook) expected_order = 1 if show_dag: from dagrt.language import show_dependency_graph show_dependency_graph(code) h = -0.5 y_0 = 1.0 def rhs(t, y): return h * y def soln(t): return y_0 * np.exp(h * t) from pytools.convergence import EOCRecorder eocrec = EOCRecorder() for n in range(1, 5): dt = 2**(-n) t = 0.0 y = y_0 final_t = 1 from functools import partial interp = python_method_impl(code, function_map={ method.rhs_func.name: rhs, "<func>solver": partial(solver, rhs) }) interp.set_up(t_start=t, dt_start=dt, context={component_id: y}) times = [] values = [] for event in interp.run(t_end=final_t): if isinstance(event, interp.StateComputed): assert event.component_id == component_id values.append(event.state_component) times.append(event.t) assert abs(times[-1] - final_t) < 1e-10 times = np.array(times) if plot_solution: import matplotlib.pyplot as pt pt.plot(times, values, label="comp") pt.plot(times, soln(times), label="true") pt.show() error = abs(values[-1] - soln(final_t)) eocrec.add_data_point(dt, error) print("------------------------------------------------------") print("%s: expected order %d" % (method, expected_order)) print("------------------------------------------------------") print(eocrec.pretty_print()) orderest = eocrec.estimate_order_of_convergence()[0, 1] assert orderest > expected_order * 0.9
def main(show_dag=False, plot_solution=False): component_id = "y" method = ODE23Method(component_id, use_high_order=True) expected_order = 3 # Use "DEBUG" to trace execution logging.basicConfig(level=logging.INFO) code = method.generate() if show_dag: from dagrt.language import show_dependency_graph show_dependency_graph(code) from dagrt.exec_numpy import NumpyInterpreter def rhs(t, y): u, v = y return np.array([v, -u/t**2], dtype=np.float64) def soln(t): inner = np.sqrt(3)/2*np.log(t) return np.sqrt(t)*( 5*np.sqrt(3)/3*np.sin(inner) + np.cos(inner) ) from pytools.convergence import EOCRecorder eocrec = EOCRecorder() for n in range(4, 7): dt = 2**(-n) t = 1 y = np.array([1, 3], dtype=np.float64) final_t = 10 interp = NumpyInterpreter(code, function_map={"<func>" + component_id: rhs}) interp.set_up(t_start=t, dt_start=dt, context={component_id: y}) times = [] values = [] for event in interp.run(t_end=final_t): if isinstance(event, interp.StateComputed): assert event.component_id == component_id values.append(event.state_component[0]) times.append(event.t) assert abs(times[-1] - final_t) < 1e-10 times = np.array(times) if plot_solution: import matplotlib.pyplot as pt pt.plot(times, values, label="comp") pt.plot(times, soln(times), label="true") pt.show() error = abs(values[-1]-soln(final_t)) eocrec.add_data_point(dt, error) print("------------------------------------------------------") print("%s: expected order %d" % (method, expected_order)) print("------------------------------------------------------") print(eocrec.pretty_print()) orderest = eocrec.estimate_order_of_convergence()[0, 1] assert orderest > expected_order*0.95
def test_adaptive_timestep(python_method_impl, method, show_dag=False, plot=False): # Use "DEBUG" to trace execution logging.basicConfig(level=logging.INFO) component_id = method.component_id code = method.generate() print(code) #1/0 if show_dag: from dagrt.language import show_dependency_graph show_dependency_graph(code) from stiff_test_systems import VanDerPolProblem example = VanDerPolProblem() y = example.initial() interp = python_method_impl( code, function_map={"<func>" + component_id: example}) interp.set_up(t_start=example.t_start, dt_start=1e-5, context={component_id: y}) times = [] values = [] new_times = [] new_values = [] last_t = 0 step_sizes = [] for event in interp.run(t_end=example.t_end): if isinstance(event, interp.StateComputed): assert event.component_id == component_id new_values.append(event.state_component) new_times.append(event.t) elif isinstance(event, interp.StepCompleted): if not new_times: continue step_sizes.append(event.t - last_t) last_t = event.t times.extend(new_times) values.extend(new_values) del new_times[:] del new_values[:] elif isinstance(event, interp.StepFailed): del new_times[:] del new_values[:] logger.info("failed step at t=%s" % event.t) times = np.array(times) values = np.array(values) step_sizes = np.array(step_sizes) if plot: import matplotlib.pyplot as pt pt.plot(times, values[:, 1], "x-") pt.show() pt.plot(times, step_sizes, "x-") pt.show() step_sizes = np.array(step_sizes) small_step_frac = len(np.nonzero(step_sizes < 0.01)[0]) / len(step_sizes) big_step_frac = len(np.nonzero(step_sizes > 0.05)[0]) / len(step_sizes) print("small_step_frac (<0.01): %g - big_step_frac (>.05): %g" % (small_step_frac, big_step_frac)) assert small_step_frac <= 0.35, small_step_frac assert big_step_frac >= 0.16, big_step_frac