import%20marimo%0A%0A__generated_with%20%3D%20%220.9.27%22%0Aapp%20%3D%20marimo.App(width%3D%22medium%22)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20__(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%23%20%C2%A75%20%E5%8F%8C%E6%9B%B2%E6%96%B9%E7%A8%8B%E7%9A%84%E5%B7%AE%E5%88%86%E6%96%B9%E6%B3%95%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20__(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%23%23%20%E5%87%86%E5%A4%87%E5%B7%A5%E4%BD%9C%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20__()%3A%0A%20%20%20%20import%20marimo%20as%20mo%0A%20%20%20%20return%20(mo%2C)%0A%0A%0A%40app.cell%0Adef%20__()%3A%0A%20%20%20%20import%20numpy%20as%20np%0A%20%20%20%20from%20numpy%20import%20linalg%2C%20newaxis%0A%0A%20%20%20%20np.set_printoptions(precision%3D3%2C%20suppress%3DTrue)%0A%20%20%20%20return%20linalg%2C%20newaxis%2C%20np%0A%0A%0A%40app.cell%0Adef%20__()%3A%0A%20%20%20%20from%20matplotlib%20import%20pyplot%20as%20plt%0A%20%20%20%20return%20(plt%2C)%0A%0A%0A%40app.cell%0Adef%20__()%3A%0A%20%20%20%20from%20typing%20import%20override%0A%20%20%20%20return%20(override%2C)%0A%0A%0A%40app.cell%0Adef%20__()%3A%0A%20%20%20%20from%20hyperbolic_pde%20import%20Solver%2C%20benchmark%2C%20plot_benchmark%2C%20ref%0A%20%20%20%20return%20Solver%2C%20benchmark%2C%20plot_benchmark%2C%20ref%0A%0A%0A%40app.cell%0Adef%20__()%3A%0A%20%20%20%20from%20util%20import%20multi_diag%2C%20plot_surface%2C%20show_files%2C%20typst%0A%20%20%20%20return%20multi_diag%2C%20plot_surface%2C%20show_files%2C%20typst%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20__(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%23%23%20%E9%97%AE%E9%A2%98%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20__()%3A%0A%20%20%20%20a%20%3D%205%0A%20%20%20%20return%20(a%2C)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20__(a%2C%20typst)%3A%0A%20%20%20%20typst(rf%22%22%22%0A%20%20%20%20%23import%20%22%40preview%2Fphysica%3A0.9.3%22%3A%20pdv%2C%20eval%0A%0A%20%20%20%20%24%0A%20%20%20%20pdv(u%2Ct)%20%2B%20%7Ba%7D%20pdv(u%2Cx)%20%3D%200%2C%20x%20in%20RR.%20%5C%0A%20%20%20%20eval(u)_(t%3D0)%20%3D%20cases(%0A%20%20%20%20%20%202%20%26%22if%22%20x%20in%20(-1%2C0)%2C%0A%20%20%20%20%20%201%20%26%22if%22%20x%20%3D%200%2C%0A%20%20%20%20%20%20-2%20%26%22if%22%20x%20in%20(0%2C1)%2C%0A%20%20%20%20%20%200%20%26%22otherwise%22%0A%20%20%20%20).%0A%20%20%20%20%24%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20__(mo)%3A%0A%20%20%20%20dx%20%3D%20mo.ui.slider(%0A%20%20%20%20%20%20%20%200.02%2C%200.1%2C%200.02%2C%20label%3Dr%22%24%5Cmathrm%7Bd%7D%20x%24%22%2C%20show_value%3DTrue%2C%20debounce%3DTrue%0A%20%20%20%20)%0A%20%20%20%20dx%0A%20%20%20%20return%20(dx%2C)%0A%0A%0A%40app.cell%0Adef%20__()%3A%0A%20%20%20%20r%20%3D%201%20%2F%206%0A%20%20%20%20return%20(r%2C)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20__(dx%2C%20mo%2C%20r)%3A%0A%20%20%20%20dt%20%3D%20r%20*%20dx.value%0A%20%20%20%20mo.md(rf%22%24%5Cmathrm%7B%7Bd%7D%7Dt%20%3D%20%7Bdt%7D%24.%22)%0A%20%20%20%20return%20(dt%2C)%0A%0A%0A%40app.cell%0Adef%20__(dx%2C%20np)%3A%0A%20%20%20%20x%20%3D%20np.arange(-1.5%2C%205%20%2B%20dx.value%2C%20dx.value)%0A%20%20%20%20return%20(x%2C)%0A%0A%0A%40app.cell%0Adef%20__(dt%2C%20np)%3A%0A%20%20%20%20t%20%3D%20np.arange(0%2C%201.0%2C%20dt)%0A%20%20%20%20return%20(t%2C)%0A%0A%0A%40app.cell%0Adef%20__(plot_surface%2C%20ref%2C%20t%2C%20x)%3A%0A%20%20%20%20plot_surface(t%2C%20x%2C%20ref(t%2C%20x)%2C%20title%3D%22%E7%9C%9F%E8%A7%A3%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20__(np%2C%20t%2C%20x)%3A%0A%20%20%20%20benchmark_kwargs%20%3D%20dict(%0A%20%20%20%20%20%20%20%20x_max%3Dx%5B-1%5D%2C%0A%20%20%20%20%20%20%20%20x_min%3Dx%5B0%5D%2C%0A%20%20%20%20%20%20%20%20t_max%3Dx%5B-1%5D%2C%0A%20%20%20%20%20%20%20%20t_min%3Dt%5B0%5D%2C%0A%20%20%20%20%20%20%20%20dt_dx_list%3D%5B(_dx%20%2F%206%2C%20_dx)%20for%20_dx%20in%202.0%20**%20np.arange(-7%2C%20-3%2C%201)%5D%2C%0A%20%20%20%20)%0A%20%20%20%20return%20(benchmark_kwargs%2C)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20__(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%23%23%201%20%E8%BF%8E%E9%A3%8E%EF%BC%88wind%EF%BC%89%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20__(Solver%2C%20a%2C%20multi_diag%2C%20np%2C%20override)%3A%0A%20%20%20%20class%20SolverWind(Solver)%3A%0A%20%20%20%20%20%20%20%20%40override%0A%20%20%20%20%20%20%20%20def%20post_init(self)%20-%3E%20None%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20to_next_u%5B%23next_x%2C%20%23current_x%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20self.to_next_u%20%3D%20(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20np.eye(self.x.size)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2B%20a%20*%20self.dt%20*%20multi_diag(%5B1%2C%20-1%2C%200%5D%2C%20size%3Dself.x.size)%20%2F%20self.dx%0A%20%20%20%20%20%20%20%20%20%20%20%20)%0A%0A%20%20%20%20%20%20%20%20%40override%0A%20%20%20%20%20%20%20%20def%20step(self%2C%20t)%20-%3E%20None%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20self.u%5B%3A%2C%20t%5D%20%3D%20self.to_next_u%20%40%20self.u%5B%3A%2C%20t%20-%201%5D%0A%20%20%20%20return%20(SolverWind%2C)%0A%0A%0A%40app.cell%0Adef%20__(SolverWind%2C%20t%2C%20x)%3A%0A%20%20%20%20solver_wind%20%3D%20SolverWind(t%3Dt%2C%20x%3Dx)%0A%20%20%20%20solver_wind.solve()%0A%20%20%20%20solver_wind.to_next_u%0A%20%20%20%20return%20(solver_wind%2C)%0A%0A%0A%40app.cell%0Adef%20__(plot_surface%2C%20solver_wind%2C%20t%2C%20x)%3A%0A%20%20%20%20plot_surface(t%2C%20x%2C%20solver_wind.u%2C%20title%3D%22%E8%BF%91%E4%BC%BC%E8%A7%A3%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20__(plot_surface%2C%20solver_wind%2C%20t%2C%20x)%3A%0A%20%20%20%20plot_surface(t%2C%20x%2C%20solver_wind.error()%2C%20title%3D%22%E8%AF%AF%E5%B7%AE%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20__(mo)%3A%0A%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20r%22%22%22%0A%20%20%20%20%20%20%20%20%E4%B8%BA%E4%BD%95%E6%AF%9B%E5%88%BA%E8%BF%99%E4%B9%88%E5%A4%9A%EF%BC%9F%EF%BC%81%60%E2%94%97%7C%EF%BD%80O%E2%80%B2%7C%E2%94%9B%60%0A%0A%20%20%20%20%20%20%20%20%E6%AF%9B%E5%88%BA%E5%A4%AA%E5%BD%B1%E5%93%8D%E6%9C%80%E5%A4%A7%E8%AF%AF%E5%B7%AE%E4%BA%86%EF%BC%8C%E5%A4%A7%E5%AE%B6%E9%83%BD%E6%98%AF%20%242%24%20%E7%9A%84%E9%87%8F%E7%BA%A7%EF%BC%8C%E6%8C%87%E6%A0%87%E6%97%A0%E6%95%88%E3%80%82%E6%88%91%E4%BB%AC%E5%90%8E%E9%9D%A2%E6%94%B9%E7%94%A8%E5%B9%B3%E5%9D%87%E8%AF%AF%E5%B7%AE%E8%AF%84%E4%BC%B0%E3%80%82%0A%20%20%20%20%20%20%20%20%22%22%22%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20__(solver_wind)%3A%0A%20%20%20%20solver_wind.max_error()%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20__(solver_wind)%3A%0A%20%20%20%20solver_wind.mean_error()%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20__(SolverWind%2C%20benchmark%2C%20benchmark_kwargs%2C%20plot_benchmark)%3A%0A%20%20%20%20_b%20%3D%20benchmark(SolverWind%2C%20**benchmark_kwargs)%0A%20%20%20%20plot_benchmark(_b)%5B0%5D%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20__(mo)%3A%0A%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20r%22%22%22%0A%20%20%20%20%20%20%20%20%23%23%202%20%E8%9B%99%E8%B7%B3%EF%BC%88frog%EF%BC%89%0A%0A%20%20%20%20%20%20%20%20%E8%BF%99%E6%98%AF%E4%B8%89%E5%B1%82%E6%A0%BC%E5%BC%8F%EF%BC%8C%E5%88%9D%E5%A7%8B%E7%AC%AC%E4%B8%80%E5%B1%82%E7%94%A8%E8%BF%8E%E9%A3%8E%E6%A0%BC%E5%BC%8F%E3%80%82%0A%20%20%20%20%20%20%20%20%22%22%22%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20__(Solver%2C%20a%2C%20multi_diag%2C%20override)%3A%0A%20%20%20%20class%20SolverFrog(Solver)%3A%0A%20%20%20%20%20%20%20%20%40override%0A%20%20%20%20%20%20%20%20def%20step(self%2C%20t)%20-%3E%20None%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20t%20%3E%3D%202%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20self.u%5B%3A%2C%20t%5D%20%3D%20self.u%5B%3A%2C%20t%20-%202%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20self.u%5B1%3A-1%2C%20t%5D%20-%3D%20(a%20*%20self.dt%20%2F%20self.dx)%20*%20(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20self.u%5B2%3A%2C%20t%20-%201%5D%20-%20self.u%5B%3A-2%2C%20t%20-%201%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%23%20%E8%BF%8E%E9%A3%8E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20self.u%5B%3A%2C%20t%5D%20%3D%20(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20self.u%5B%3A%2C%20t%20-%201%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2B%20(a%20*%20self.dt%20%2F%20self.dx)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20multi_diag(%5B1%2C%20-1%2C%200%5D%2C%20size%3Dself.x.size)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%40%20self.u%5B%3A%2C%20t%20-%201%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20)%0A%20%20%20%20return%20(SolverFrog%2C)%0A%0A%0A%40app.cell%0Adef%20__(SolverFrog%2C%20t%2C%20x)%3A%0A%20%20%20%20solver_frog%20%3D%20SolverFrog(t%3Dt%2C%20x%3Dx)%0A%20%20%20%20solver_frog.solve()%0A%20%20%20%20return%20(solver_frog%2C)%0A%0A%0A%40app.cell%0Adef%20__(plot_surface%2C%20solver_frog%2C%20t%2C%20x)%3A%0A%20%20%20%20plot_surface(t%2C%20x%2C%20solver_frog.u%2C%20title%3D%22%E8%BF%91%E4%BC%BC%E8%A7%A3%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20__(plot_surface%2C%20solver_frog%2C%20t%2C%20x)%3A%0A%20%20%20%20plot_surface(t%2C%20x%2C%20solver_frog.error()%2C%20title%3D%22%E8%AF%AF%E5%B7%AE%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20__(solver_frog)%3A%0A%20%20%20%20solver_frog.max_error()%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20__(solver_frog)%3A%0A%20%20%20%20solver_frog.mean_error()%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20__(SolverFrog%2C%20benchmark%2C%20benchmark_kwargs%2C%20plot_benchmark)%3A%0A%20%20%20%20_b%20%3D%20benchmark(SolverFrog%2C%20**benchmark_kwargs)%0A%20%20%20%20plot_benchmark(_b)%5B0%5D%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20__(mo)%3A%0A%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20r%22%22%22%0A%20%20%20%20%20%20%20%20%23%23%203%20Crank%E2%80%93Nicolson%EF%BC%88cn%EF%BC%89%0A%0A%20%20%20%20%20%20%20%20%E8%AF%95%E8%AF%95%5B%60scipy.sparse%60%5D(https%3A%2F%2Fdocs.scipy.org%2Fdoc%2Fscipy%2Freference%2Fsparse.html)%E3%80%82%0A%20%20%20%20%20%20%20%20%22%22%22%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20__()%3A%0A%20%20%20%20from%20scipy.sparse%20import%20diags_array%0A%20%20%20%20from%20scipy.sparse.linalg%20import%20spsolve%0A%20%20%20%20return%20diags_array%2C%20spsolve%0A%0A%0A%40app.cell%0Adef%20__(diags_array%2C%20np)%3A%0A%20%20%20%20diags_array(%5Bnp.ones(3)%2C%20np.ones(2)%20*%202%5D%2C%20offsets%3D%5B0%2C%201%5D)%20%40%20%5B100%2C%2010%2C%201%5D%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20__(diags_array)%3A%0A%20%20%20%20%23%20Broadcasting%20of%20scalars%20is%20supported%20(but%20shape%20needs%20to%20be%20specified)%0A%20%20%20%20diags_array(%5B1%2C%202%5D%2C%20offsets%3D%5B0%2C%201%5D%2C%20shape%3D(3%2C%203))%20%40%20%5B100%2C%2010%2C%201%5D%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20__(Solver%2C%20a%2C%20diags_array%2C%20np%2C%20override%2C%20spsolve)%3A%0A%20%20%20%20class%20SolverCrankNicolson(Solver)%3A%0A%20%20%20%20%20%20%20%20%40override%0A%20%20%20%20%20%20%20%20def%20post_init(self)%20-%3E%20None%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20a_current%5B%23previous_x%2C%20%23current_x%5D%20(without%20boundary)%0A%20%20%20%20%20%20%20%20%20%20%20%20self.a_current%20%3D%20diags_array(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%201%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20self.dt%20*%20a%20%2F%202%20%2F%20(2%20*%20self.dx)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20-self.dt%20*%20a%20%2F%202%20%2F%20(2%20*%20self.dx)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20offsets%3D%5B0%2C%201%2C%20-1%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20shape%3D(self.x.size%20-%202%2C%20self.x.size%20-%202)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%23%20To%20perform%20inversion%2C%20first%20convert%20to%20either%20CSC%20or%20CSR%20format.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20format%3D%22csc%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20self.rhs%20%3D%20np.empty(self.x.size%20-%202)%0A%0A%20%20%20%20%20%20%20%20%40override%0A%20%20%20%20%20%20%20%20def%20step(self%2C%20t)%20-%3E%20None%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20A%20%40%20u_current%20%2B%20A'%20%40%20u_previous%20%3D%200%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20self.rhs%5B%3A%5D%20%3D%20-self.u%5B1%3A-1%2C%20t%20-%201%5D%20%2B%20self.dt%20*%20a%20%2F%202%20*%20(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20self.u%5B2%3A%2C%20t%20-%201%5D%20-%20self.u%5B%3A-2%2C%20t%20-%201%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20)%20%2F%20(2%20*%20self.dx)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20self.u%5B1%3A-1%2C%20t%5D%20%3D%20spsolve(self.a_current%2C%20-self.rhs)%0A%0A%20%20%20%20%20%20%20%20%40override%0A%20%20%20%20%20%20%20%20def%20validate(self%2C%20t%3A%20int)%20-%3E%20None%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20(%E2%88%82%2F%E2%88%82x)%5B%23x_without_boundary%2C%20%23x_with_boundary%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20dv_x%20%3D%20diags_array(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5B1%2C%20-1%5D%2C%20offsets%3D%5B0%2C%202%5D%2C%20shape%3D(self.x.size%20-%202%2C%20self.x.size)%0A%20%20%20%20%20%20%20%20%20%20%20%20)%20%2F%20(2%20*%20self.dx)%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20(approximate%20%E2%88%82u%2F%E2%88%82x)%5B%23x_without_boundary%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20approx_dv_x%20%3D%20dv_x%20%40%20(self.u%5B%3A%2C%20t%5D%20%2B%20self.u%5B%3A%2C%20t%20-%201%5D)%20%2F%202%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20(approximate%20%E2%88%82u%2F%E2%88%82t)%5B%23x_without_boundary%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20approx_dv_t%20%3D%20(self.u%5B1%3A-1%2C%20t%5D%20-%20self.u%5B1%3A-1%2C%20t%20-%201%5D)%20%2F%20self.dt%0A%20%20%20%20%20%20%20%20%20%20%20%20assert%20np.allclose(approx_dv_t%2C%20a%20*%20approx_dv_x)%0A%20%20%20%20return%20(SolverCrankNicolson%2C)%0A%0A%0A%40app.cell%0Adef%20__(SolverCrankNicolson%2C%20t%2C%20x)%3A%0A%20%20%20%20solver_cn%20%3D%20SolverCrankNicolson(t%3Dt%2C%20x%3Dx)%0A%20%20%20%20solver_cn.solve()%0A%0A%20%20%20%20%23%20Validate%20the%20last%20%60t%60%0A%20%20%20%20solver_cn.validate(solver_cn.t.size%20-%201)%0A%0A%20%20%20%20solver_cn.a_current.toarray()%0A%20%20%20%20return%20(solver_cn%2C)%0A%0A%0A%40app.cell%0Adef%20__(plot_surface%2C%20solver_cn%2C%20t%2C%20x)%3A%0A%20%20%20%20plot_surface(t%2C%20x%2C%20solver_cn.u%2C%20title%3D%22%E8%BF%91%E4%BC%BC%E8%A7%A3%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20__(plot_surface%2C%20solver_cn%2C%20t%2C%20x)%3A%0A%20%20%20%20plot_surface(t%2C%20x%2C%20solver_cn.error()%2C%20title%3D%22%E8%AF%AF%E5%B7%AE%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20__(solver_cn)%3A%0A%20%20%20%20solver_cn.max_error()%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20__(solver_cn)%3A%0A%20%20%20%20solver_cn.mean_error()%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20__(SolverCrankNicolson%2C%20benchmark%2C%20benchmark_kwargs%2C%20plot_benchmark)%3A%0A%20%20%20%20_b%20%3D%20benchmark(SolverCrankNicolson%2C%20**benchmark_kwargs)%0A%20%20%20%20plot_benchmark(_b)%5B0%5D%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20__(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%23%23%20%E9%99%84%E5%BD%95%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20__(show_files)%3A%0A%20%20%20%20show_files(%5B%22pyproject.toml%22%2C%20%22hyperbolic_pde.py%22%2C%20%22util.py%22%5D)%0A%20%20%20%20return%0A%0A%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20app.run()%0A
2feadfc5fcb32b67eb4ba68d2ebf0423ba88efc6fe9a425db37369d6c59e5c33