Table of contents

Preface
Vibration ODEs
      Finite difference discretization
            A basic model for vibrations
            A centered finite difference scheme
      Implementation
            Making a solver function
            Verification
            Scaled model
      Long time simulations
            Using a moving plot window
            Making animations
            Using Bokeh to compare graphs
            Using a line-by-line ascii plotter
            Empirical analysis of the solution
      Analysis of the numerical scheme
            Deriving a solution of the numerical scheme
            Exact discrete solution
            Convergence
            The global error
            Stability
            About the accuracy at the stability limit
      Alternative schemes based on 1st-order equations
            The Forward Euler scheme
            The Backward Euler scheme
            The Crank-Nicolson scheme
            Comparison of schemes
            Runge-Kutta methods
            Analysis of the Forward Euler scheme
      Energy considerations
            Derivation of the energy expression
            An error measure based on energy
      The Euler-Cromer method
            Forward-backward discretization
            Equivalence with the scheme for the second-order ODE
            Implementation
            The velocity Verlet algorithm
      Generalization: damping, nonlinear spring, and external excitation
            A centered scheme for linear damping
            A centered scheme for quadratic damping
            A forward-backward discretization of the quadratic damping term
            Implementation
            Verification
            Visualization
            User interface
            The Euler-Cromer scheme for the generalized model
      Exercises and Problems
            Problem 1: Use linear/quadratic functions for verification
            Exercise 2: Show linear growth of the phase with time
            Exercise 3: Improve the accuracy by adjusting the frequency
            Exercise 4: See if adaptive methods improve the phase error
            Exercise 5: Use a Taylor polynomial to compute \( u^1 \)
            Exercise 6: Find the minimal resolution of an oscillatory function
            Exercise 7: Visualize the accuracy of finite differences for a cosine function
            Exercise 8: Verify convergence rates of the error in energy
            Exercise 9: Use linear/quadratic functions for verification
            Exercise 10: Use an exact discrete solution for verification
            Exercise 11: Use analytical solution for convergence rate tests
            Exercise 12: Investigate the amplitude errors of many solvers
            Exercise 13: Minimize memory usage of a vibration solver
            Exercise 14: Implement the solver via classes
            Exercise 15: Interpret \( [D_tD_t u]^n \) as a forward-backward difference
            Exercise 16: Use a backward difference for the damping term
            Exercise 17: Analysis of the Euler-Cromer scheme
Wave equations
      Simulation of waves on a string
            Discretizing the domain
            The discrete solution
            Fulfilling the equation at the mesh points
            Replacing derivatives by finite differences
            Formulating a recursive algorithm
            Sketch of an implementation
      Verification
            A slightly generalized model problem
            Using an analytical solution of physical significance
            Manufactured solution
            Constructing an exact solution of the discrete equations
      Implementation
            Callback function for user-specific actions
            The solver function
            Verification: exact quadratic solution
            Visualization: animating the solution
            Running a case
            Working with a scaled PDE model
      Vectorization
            Operations on slices of arrays
            Finite difference schemes expressed as slices
            Verification
            Efficiency measurements
            Remark on the updating of arrays
      Exercises
            Exercise 18: Simulate a standing wave
            Exercise 19: Add storage of solution in a user action function
            Exercise 20: Use a class for the user action function
            Exercise 21: Compare several Courant numbers in one movie
            Project 22: Calculus with 1D mesh functions
      Generalization: reflecting boundaries
            Neumann boundary condition
            Discretization of derivatives at the boundary
            Implementation of Neumann conditions
            Index set notation
            Verifying the implementation of Neumann conditions
            Alternative implementation via ghost cells
      Generalization: variable wave velocity
            The model PDE with a variable coefficient
            Discretizing the variable coefficient
            Computing the coefficient between mesh points
            How a variable coefficient affects the stability
            Neumann condition and a variable coefficient
            Implementation of variable coefficients
            A more general PDE model with variable coefficients
            Generalization: damping
      Building a general 1D wave equation solver
            User action function as a class
            Pulse propagation in two media
      Exercises
            Exercise 23: Find the analytical solution to a damped wave equation
            Problem 24: Explore symmetry boundary conditions
            Exercise 25: Send pulse waves through a layered medium
            Exercise 26: Explain why numerical noise occurs
            Exercise 27: Investigate harmonic averaging in a 1D model
            Problem 28: Implement open boundary conditions
            Exercise 29: Implement periodic boundary conditions
            Exercise 30: Compare discretizations of a Neumann condition
            Exercise 31: Verification by a cubic polynomial in space
      Analysis of the difference equations
            Properties of the solution of the wave equation
            More precise definition of Fourier representations
            Stability
            Numerical dispersion relation
            Extending the analysis to 2D and 3D
      Finite difference methods for 2D and 3D wave equations
            Multi-dimensional wave equations
            Mesh
            Discretization
      Implementation
            Scalar computations
            Vectorized computations
            Verification
      Using classes to implement a simulator
      Exercises
            Exercise 32: Check that a solution fulfills the discrete model
            Project 33: Calculus with 2D mesh functions
            Exercise 34: Implement Neumann conditions in 2D
            Exercise 35: Test the efficiency of compiled loops in 3D
      Applications of wave equations
            Waves on a string
            Waves on a membrane
            Elastic waves in a rod
            The acoustic model for seismic waves
            Sound waves in liquids and gases
            Spherical waves
            The linear shallow water equations
            Waves in blood vessels
            Electromagnetic waves
      Exercises
            Exercise 36: Simulate waves on a non-homogeneous string
            Exercise 37: Simulate damped waves on a string
            Exercise 38: Simulate elastic waves in a rod
            Exercise 39: Simulate spherical waves
            Problem 40: Earthquake-generated tsunami over a subsea hill
            Problem 41: Earthquake-generated tsunami over a 3D hill
            Problem 42: Investigate Matplotlib for visualization
            Problem 43: Investigate visualization packages
            Problem 44: Implement loops in compiled languages
            Exercise 45: Simulate seismic waves in 2D
            Project 46: Model 3D acoustic waves in a room
            Project 47: Solve a 1D transport equation
            Problem 48: General analytical solution of a 1D damped wave equation
            Problem 49: General analytical solution of a 2D damped wave equation
Diffusion equations
      The 1D diffusion equation
            The initial-boundary value problem for 1D diffusion
            Forward Euler scheme
            Backward Euler scheme
            Sparse matrix implementation
            Crank-Nicolson scheme
            The \( \theta \) rule
            The Laplace and Poisson equation
            Extensions
      Analysis of schemes for the diffusion equation
            Properties of the solution
            Example: Diffusion of a discontinues profile
            Analysis of discrete equations
            Analysis of the finite difference schemes
            Analysis of the Forward Euler scheme
            Analysis of the Backward Euler scheme
            Analysis of the Crank-Nicolson scheme
            Summary of accuracy of amplification factors
            Exercise 50: Explore symmetry in a 1D problem
            Exercise 51: Investigate approximation errors from a \( u_x=0 \) boundary condition
            Exercise 52: Experiment with open boundary conditions in 1D
            Exercise 53: Simulate a diffused Gaussian peak in 2D/3D
            Exercise 54: Examine stability of a diffusion model with a source term
      Diffusion in heterogeneous media
            Stationary solution
            Piecewise constant medium
            Implementation
            Diffusion equation in axi-symmetric geometries
            Diffusion equation in spherically-symmetric geometries
      Exercises
            Exercise 55: Stabilizing the Crank-Nicolson method by Rannacher time stepping
            Project 56: Energy estimates for diffusion problems
Staggered mesh discretization
            The Euler-Cromer scheme on a standard mesh
            The Euler-Cromer scheme on a staggered mesh
            Implementation of the scheme on a staggered mesh
            A staggered Euler-Cromer scheme for a generalized model
      Exercises
            Exercise 57: Use the forward-backward scheme with quadratic damping
Appendix: Useful formulas
      Finite difference operator notation
      Truncation errors of finite difference approximations
      Finite differences of exponential functions
      Finite differences of \( t^n \)
Appendix: Truncation error analysis
      Overview of truncation error analysis
            Abstract problem setting
            Error measures
      Truncation errors in finite difference formulas
            Example: The backward difference for \( u'(t) \)
            Example: The forward difference for \( u'(t) \)
            Example: The central difference for \( u'(t) \)
            Overview of leading-order error terms in finite difference formulas
            Software for computing truncation errors
      Truncation errors in exponential decay ODE
            Truncation error of the Forward Euler scheme
            Truncation error of the Crank-Nicolson scheme
            Truncation error of the \( \theta \)-rule
            Using symbolic software
            Empirical verification of the truncation error
            Increasing the accuracy by adding correction terms
            Extension to variable coefficients
            Exact solutions of the finite difference equations
            Computing truncation errors in nonlinear problems
      Truncation errors in vibration ODEs
            Linear model without damping
            Model with damping and nonlinearity
            Extension to quadratic damping
            The general model formulated as first-order ODEs
      Truncation errors in wave equations
            Linear wave equation in 1D
            Finding correction terms
            Extension to variable coefficients
            1D wave equation on a staggered mesh
            Linear wave equation in 2D/3D
      Truncation errors in diffusion equations
            Linear diffusion equation in 1D
            Linear diffusion equation in 2D/3D
            A nonlinear diffusion equation in 2D
      Exercises
            Exercise 58: Truncation error of a weighted mean
            Exercise 59: Simulate the error of a weighted mean
            Exercise 60: Verify a truncation error formula
            Exercise 61: Truncation error of the Backward Euler scheme
            Exercise 62: Empirical estimation of truncation errors
            Exercise 63: Correction term for a Backward Euler scheme
            Exercise 64: Verify the effect of correction terms
            Exercise 65: Truncation error of the Crank-Nicolson scheme
            Exercise 66: Truncation error of \( u'=f(u,t) \)
            Exercise 67: Truncation error of \( [D_t D_tu]^n \)
            Exercise 68: Investigate the impact of approximating \( u'(0) \)
            Exercise 69: Investigate the accuracy of a simplified scheme
Appendix: Software engineering; wave equation model
      A 1D wave equation simulator
            Mathematical model
            Numerical discretization
            A solver function
      Saving large arrays in files
            Using savez to store arrays in files
            Using joblib to store arrays in files
            Using a hash to create a file or directory name
      Software for the 1D wave equation
            Making hash strings from input data
            Avoiding rerunning previously run cases
            Verification
      Programming the solver with classes
            Class Problem
            Class Mesh
            Class Function
            Class Solver
      Migrating loops to Cython
            Declaring variables and annotating the code
            Visual inspection of the C translation
            Building the extension module
            Calling the Cython function from Python
      Migrating loops to Fortran
            The Fortran subroutine
            Building the Fortran module with f2py
            How to avoid array copying
      Migrating loops to C via Cython
            Translating index pairs to single indices
            The complete C code
            The Cython interface file
            Building the extension module
      Migrating loops to C via f2py
            Migrating loops to C++ via f2py
      Exercises
            Exercise 70: Make an improved numpy.savez function
      References