Starting with the advection equation is conservative form, $$ \frac{\partial u}{\partial t} = -\frac{\partial (\boldsymbol{v} u)}{\partial x} + s(x,t) $$ The Crank-Nicolson method consists of a time averaged centered difference. $$\frac{u_{j}^{n+1} - u_{j}^{n}}{\Delta t} = -\boldsymbol{v} \left[ \frac{1-\beta}{2\Delta x} \left( u_{j+1}^{n} - u_{j-1}^{n} \right) + \frac{\beta}{2\Delta x} \left( u_{j+1}^{n+1} - u_{j-1}^{n+1} \right) \right] + s(x,t)$$ Regarding the notation, *subscripts* are for points in space, and the *superscripts* are for points in time. The points at $n+1$ are in the future: they are unknowns. We now need to rearrange the above equation so that all *knowns* are on the r.h.s and *unknowns* are on the l.h.s.. Making the substitution, $$ r = \frac{\boldsymbol{v}}{2}\frac{\Delta t}{\Delta x} $$ gives, $$-\beta r\phi_{j-1}^{n+1} + \phi_{j}^{n+1} + \beta r\phi_{j+1}^{n+1} = (1-\beta)r\phi_{j-1}^{n} + \phi_{j}^{n} - (1-\beta)r\phi_{j+1}^{n}$$ This is the advection equation discretised using the Crank-Nicolson method. You can write it as a matrix equation, $$ \begin{pmatrix} 1 & \beta r & & & 0 \\ -\beta r & 1 & \beta r & & \\ & \ddots & \ddots & \ddots & \\ & & -\beta r & 1 & \beta r \\ 0 & & & -\beta r & 1 \\ \end{pmatrix} \begin{pmatrix} u_1^{n+1} \\ u_2^{n+1} \\ \vdots \\ u_{J-1}^{n+1} \\ u_{J}^{n+1} \\ \end{pmatrix} = \begin{pmatrix} 1 & -(1 - \beta)r & & & 0 \\ (1 - \beta)r & 1 & -(1 - \beta)r & & \\ & \ddots & \ddots & \ddots & \\ & & (1 - \beta)r & 1 & -(1 - \beta)r \\ 0 & & &(1 - \beta)r & 1 \\ \end{pmatrix} \begin{pmatrix} u_1^{n} \\ u_2^{n} \\ \vdots \\ u_{J-1}^{n} \\ u_{J}^{n} \\ \end{pmatrix} $$ Setting $\beta=1/2$ will give you trapezoidal integration in time, so for Crank-Nicolson this is what you want. A few words of warning. This is basic solution you wanted, but you will need to include some sort of **boundary condition** for a well-posed problem. Also, Crank-Nicolson is not necessarily the best method for the advection equation. It is second order accurate and [unconditionally stable][1], which is fantastic. However it will generate (as with all centered difference stencils) spurious oscillation if you have very sharp peaked solutions or initial conditions. I wrote the following code for you in Python, it should get you started. The code solves the advection equation for an initial Gaussian curve moving to the right with constant velocity. ![Gaussian curve moving to the right with constant velocity][2] from __future__ import division from scipy.sparse import spdiags from scipy.sparse.linalg import spsolve import numpy as np beta = 0.5 J = 200 # total number of mesh points z = np.linspace(-10,10,J) # vertices dz = abs(z[1]-z[0]) # space step dt = 0.2 # time step v = 2 * np.ones(len(z)) # velocity field (constant) r = v / 2 * dt / dz # initial conditions gaussian = lambda z, height, position, hwhm: height * np.exp(-np.log(2) * ((z - position)/hwhm)**2) u_init = gaussian(z, 1, -3, 2) def make_advection_matrices(z, r): """Return matrices A and M for advection equations""" lower = -beta * r; centre = np.ones(len(z)); upper = beta * r A = spdiags( [lower, centre, upper], (-1,0,1), len(z), len(z) ) lower = (1-beta) * r; centre = np.ones(len(z)); upper = -(1-beta) * r M = spdiags( [lower, centre, upper], (-1,0,1), len(z), len(z) ) return A.tocsr(), M.tocsr() def plot_iteration(z, u, iteration): """Plot the solver progress""" import pylab pylab.plot(z, u, label="Iteration %d" % iteration) pylab.savefig("%d_solution" % iteration) pylab.cla() A, M = make_advection_matrices(z, r) u = u_init for i in range(10): d = M * u u = spsolve(A, M * u) plot_iteration(z, u, i) [1]: http://scicomp.stackexchange.com/questions/5402/is-crank-nicolson-a-stable-discretization-scheme-for-reaction-diffusion-advectio [2]: https://i.sstatic.net/zFaVE.gif