The Diffusion Equation Solved Analytically With Python
Today, we will use Python to analytically solve one of the most important partial differential equations out there, the diffusion equation. It is a fundamental equation that arises in many areas of physics, chemistry, biology, and engineering, and has an enormous range of applications. For instance, in physics, the diffusion equation is used to describe the movement of heat through a solid or fluid, as well as the transport of particles in gases and liquids. Also, the Schrรถdinger equation is (in principle) a kind of diffusion equation. In biology, the diffusion equation is used to study the movement of nutrients and other substances through living tissues, as well as the spread of diseases. In engineering, the diffusion equation is used to design and optimize processes such as heat exchangers, catalytic converters, and solar cells. It is even applied in economics, where the diffusion equation can be used to model the spread of ideas or innovations through a population. Due to its wide range of applications, it is not surprising that it was found independently by several scientists of the 19th century working on completely different topics. The famous George Gabriel Stokes derived the equation in 1845 to describe the motion of fluids, while the even more famous James Clerk Maxwell derived the equation in 1860 to describe the motion of heat.
The equation is given by:
where t is time, ๐ผ a constant, and โยฒ is the Laplacian operator. For concreteness, we will solve the following example application. We have a 10cm long bar with insulated sides initially at 100ยฐ everywhere. Starting at ๐ก=0, the ends are held at temperature 0ยฐ. Our task is to find the temperature distribution at some later time ๐ก.
The method we will use is the separation of variables, i.e. we use the ansatz
where ๐ and ๐ are functions of a single variable ๐ก and ๐ฅ, respectively. Start a new Jupyter notebook and define the symbols for our problem:
Insert the separation ansatz:
Divide by ๐(๐ก)๐(๐ฅ):
The key observation here is that the left side depends only on t, whereas the right side depends only on x. So, when you change ๐ก, only the left side changes but not the right side. Conversely, if you change ๐ฅ, the right side changes, but not the left side. The only way how this can be true is that both sides are equal to a constant. Letโs call that constant โ๐ยฒ:
This is just an ordinary differential equation that we can easily solve:
Now focus on the side of the separated equation:
Again, a simple ODE:
Hmmmโฆ sympy uses the same names of the constants of integration, so we get a name clash. Letโs rename the constants:
Itโs more convenient to have that in terms of sines and cosines, so we can rewrite that:
The coefficients are independent, so we can simply give new names to them:
And thatโs the form we will work with.
Now consider the first boundary conditions at ๐ฅ=0. This gives a value for the constant ๐ต:
The other boundary condition gives a constraint on ๐:
Now we can assemble a solution from our base solutions.
where we have absorbed the coefficient ๐ถ into the new coefficients ๐_๐.
But this must still satisfy the initial condition, which we havenโt evaluated yet. So do that now:
We can solve for ๐_๐ by using the fact that the sines are orthogonal. So multiply both sides by a suitable sine and integrate:
The infinite sum on the left side has only one non-zero term, for which ๐=๐:
Now insert the values for the coefficients in our solution:
And that is the exact solution to our problem.
Finally, we can plot it. But of course, we have to cut off the series at some point. We will approximate the solution by the first 30 terms:
Now we can plot the solution with the
sympy
plotting backends
spb
: