2.4.8 Solver comparison

This example shows how to set up solvers explicitly and how to extract diagnostic information.

Deviation: 7.3e-09, 8.5e-09, explicit solver, explicit, adaptive solver, scipy solver
Diagnostic information from first run:
{'controller': {'mpi_run': False, 't_start': 0, 't_end': 1.0, 'profiler': {'solver': 0.007315090000005853, 'tracker': 4.173699998943903e-05, 'compilation': 3.4073496720000023}, 'jit_count': {'make_stepper': 10, 'simulation': 0}, 'solver_start': '2025-03-12 07:45:35.263580', 'successful': True, 'stop_reason': 'Reached final time', 'solver_duration': '0:00:00.007352', 't_final': 1.0}, 'package_version': 'unknown', 'solver': {'class': 'ExplicitSolver', 'pde_class': 'DiffusionPDE', 'scheme': 'euler', 'backend': 'numba', 'dt': 0.001, 'steps': 1000, 'post_step_data': None, 'stochastic': np.False_}}

Diagnostic information from second run:
{'controller': {'mpi_run': False, 't_start': 0, 't_end': 1.0, 'profiler': {'solver': 0.09307579299999702, 'tracker': 3.96330000000944e-05, 'compilation': 0.7647774579999975}, 'jit_count': {'make_stepper': 1, 'simulation': 0}, 'solver_start': '2025-03-12 07:45:36.036545', 'successful': True, 'stop_reason': 'Reached final time', 'solver_duration': '0:00:00.093268', 't_final': np.float64(1.0)}, 'package_version': 'unknown', 'solver': {'class': 'ExplicitSolver', 'pde_class': 'DiffusionPDE', 'dt_statistics': {'min': 0.001, 'max': 0.17091712204694182, 'mean': 0.08333333333333334, 'std': 0.05206367510573229, 'count': 12.0}, 'scheme': 'runge-kutta', 'backend': 'numba', 'dt': 0.001, 'dt_adaptive': True, 'steps': 12, 'stochastic': np.False_, 'post_step_data': None}}

Diagnostic information from third run:
{'controller': {'mpi_run': False, 't_start': 0, 't_end': 1.0, 'profiler': {'solver': 0.0021991499999955977, 'tracker': 4.0288000000998636e-05, 'compilation': 0.43752309399999945}, 'jit_count': {'make_stepper': 1, 'simulation': 0}, 'solver_start': '2025-03-12 07:45:37.345849', 'successful': True, 'stop_reason': 'Reached final time', 'solver_duration': '0:00:00.002286', 't_final': np.float64(1.0)}, 'package_version': 'unknown', 'solver': {'class': 'ScipySolver', 'pde_class': 'DiffusionPDE', 'dt': None, 'steps': 50, 'stochastic': False, 'backend': 'numba'}}

import pde

# initialize the grid, an initial condition, and the PDE
grid = pde.UnitGrid([32, 32])
field = pde.ScalarField.random_uniform(grid, -1, 1)
eq = pde.DiffusionPDE()

# try the explicit solver
solver1 = pde.ExplicitSolver(eq)
controller1 = pde.Controller(solver1, t_range=1, tracker=None)
sol1 = controller1.run(field, dt=1e-3)
sol1.label = "explicit solver"
print("Diagnostic information from first run:")
print(controller1.diagnostics)
print()

# try an explicit solver with adaptive time steps
solver2 = pde.ExplicitSolver(eq, scheme="runge-kutta", adaptive=True)
controller2 = pde.Controller(solver2, t_range=1, tracker=None)
sol2 = controller2.run(field, dt=1e-3)
sol2.label = "explicit, adaptive solver"
print("Diagnostic information from second run:")
print(controller2.diagnostics)
print()

# try the standard scipy solver
solver3 = pde.ScipySolver(eq)
controller3 = pde.Controller(solver3, t_range=1, tracker=None)
sol3 = controller3.run(field)
sol3.label = "scipy solver"
print("Diagnostic information from third run:")
print(controller3.diagnostics)
print()

# plot both fields and give the deviation as the title
deviation12 = ((sol1 - sol2) ** 2).average
deviation13 = ((sol1 - sol3) ** 2).average
title = f"Deviation: {deviation12:.2g}, {deviation13:.2g}"
pde.FieldCollection([sol1, sol2, sol3]).plot(title=title)

Total running time of the script: (0 minutes 5.795 seconds)