Key Takeaways
- Curated project ideas cover beginner, intermediate, and advanced levels, with a focus on simulation and computational science.
- Difficulty levels reflect prerequisites, math complexity, and expected time investment.
- Code templates are included for each project so students can start building quickly.
- Learning outcomes show what each project teaches.
- A skills-to-projects roadmap helps students choose a project based on their current knowledge.
Student projects in computational science and simulation are where theory finally meets code. You may learn finite volume methods, partial differential equations, and conservation laws in lectures, but equations on a whiteboard do not teach what writing a solver from scratch feels like.
If you want to understand how numerical methods translate into working simulations, pick a project and start building.
This guide curates practical project ideas inspired by university computational physics courses, open-source scientific projects, and peer repositories. Each project uses Python and builds toward something students can include in a portfolio.
Project Difficulty Levels Explained
Before choosing a project, it helps to understand what each level means in terms of effort.
| Level | Prerequisites | Expected Time | What You Will Do |
|---|---|---|---|
| Beginner | Python basics, NumPy, Matplotlib | 2–4 weeks | Solve simple ODEs or PDEs with explicit methods and visualize results |
| Intermediate | Numerical analysis, linear algebra, ODE/PDE background | 4–8 weeks | Implement solvers, handle boundary conditions, and compare accuracy |
| Advanced | Advanced numerical methods, parallel computing, or specialized physics background | 8–16 weeks | Build multi-physics simulations, optimize performance, or compare with literature results |
The table is not a ranking. It is a matching tool. Pick a level that matches your current preparation, then move upward once you are comfortable.
Skills-to-Projects Roadmap
The roadmap below shows which mathematical and programming concepts map to which projects.
┌─────────────────┬─────────────────────────────────────────────────────────┐
│ Skill / Concept │ Projects That Use It │
├─────────────────┼─────────────────────────────────────────────────────────┤
│ Python basics │ Heat equation solver, SIR epidemic model, Lennard-Jones │
│ NumPy arrays │ Wave propagation, diffusion on grid │
│ ODE solvers │ SIR model, projectile with drag, Lotka-Volterra │
│ PDE basics │ Heat equation, wave equation, diffusion │
│ Linear algebra │ Jacobi iteration, eigenvalue problems, Krylov methods │
│ Monte Carlo │ Ising model, radioactive decay, option pricing │
│ FFT / spectral │ Wave propagation, turbulence, spectral methods │
│ Parallelism │ MPI diffusion solver, GPU molecular dynamics │
│ Phase-field │ Solidification, fracture mechanics, grain boundary │
└─────────────────┴─────────────────────────────────────────────────────────┘
Beginner Projects
These projects introduce core simulation concepts without overwhelming math or complex setup. They are designed to run on a laptop without special hardware.
1. Heat Equation Solver on a Grid
Difficulty: Beginner
Time: 2–3 weeks
What you will simulate: Heat spreading through a metal plate, a rod, or a room. The 1D or 2D heat equation is a classic first project in numerical PDEs because it is conceptually simple and teaches major concepts used later.
Math model:
∂T/∂t = α ∇²T
Here, α is thermal diffusivity, T is temperature, and ∇² is the spatial Laplacian.
Python stack: NumPy, Matplotlib
Code template:
import numpy as np
import matplotlib.pyplot as plt
def heat_solver(alpha, L, dt, steps):
"""Solve the 1D heat equation with explicit finite differences."""
dx = L / 50
x = np.linspace(0, L, 51)
T = np.zeros_like(x)
T[20:31] = 1.0 # initial hot strip
history = [T.copy()]
for step in range(steps):
T_new = T.copy()
for i in range(1, len(T) - 1):
T_new[i] = T[i] + dt * alpha / dx**2 * (
T[i + 1] - 2 * T[i] + T[i - 1]
)
T = T_new
history.append(T.copy())
return x, np.array(history)
x, history = heat_solver(alpha=1.0, L=1.0, dt=0.0001, steps=1000)
plt.imshow(history, aspect="auto", extent=[0, 1, 1000, 0])
plt.xlabel("Position")
plt.ylabel("Time step")
plt.colorbar(label="Temperature")
plt.show()
Learning outcomes:
- Understanding explicit and implicit stability.
- Boundary condition implementation.
- Visualization of diffusive fields.
- Basic CFL-style stability reasoning.
Why this project: The heat equation is the “hello world” of simulation. Every later project involving diffusion, waves, or phase-field modeling builds on similar numerical patterns.
Suggested extensions:
- Switch to a fully implicit scheme or Crank-Nicolson and compare stability.
- Add a source term such as a heating element.
- Export results to CSV for analysis.
2. SIR Epidemic Spread Model
Difficulty: Beginner
Time: 2–3 weeks
What you will simulate: The classic compartmental model of disease spread: Susceptible, Infectious, and Recovered. This model captures epidemic curves, herd immunity, and the basic reproduction number without a spatial grid.
Math model:
dS/dt = -βSI/N
dI/dt = βSI/N - γI
dR/dt = γI
Here, β is the transmission rate, γ is the recovery rate, and N = S + I + R is the population.
Python stack: NumPy, SciPy, Matplotlib
Code template:
import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import odeint
def sir_model(y, t, beta, gamma):
S, I, R = y
N = S + I + R
dS = -beta * S * I / N
dI = beta * S * I / N - gamma * I
dR = gamma * I
return [dS, dI, dR]
beta, gamma = 0.5, 0.1
y0 = [990, 10, 0]
t = np.linspace(0, 100, 100)
solution = odeint(sir_model, y0, t, args=(beta, gamma))
plt.plot(t, solution)
plt.legend(["Susceptible", "Infectious", "Recovered"])
plt.xlabel("Time")
plt.ylabel("Population")
plt.show()
Learning outcomes:
- Solving systems of ODEs.
- Understanding
R₀ = β/γ. - Interpreting epidemic peaks and final size behavior.
- Plotting phase-plane behavior such as infectious versus susceptible population.
Why this project: It has real-world relevance with minimal complexity. The model is simple enough to understand but rich enough to support meaningful experiments.
Suggested extensions:
- Add age structure with multiple compartments.
- Include vaccination as a time-dependent parameter.
- Compare Euler, RK4, and SciPy ODE solvers.
3. Wave Equation on a String
Difficulty: Beginner
Time: 3–4 weeks
What you will simulate: A vibrating string, drum membrane, or sound wave. The wave equation introduces propagation, reflection, and standing waves.
Math model:
∂²u/∂t² = c² ∇²u
Boundary conditions can be fixed, free, or mixed.
Python stack: NumPy, Matplotlib
Code template:
import numpy as np
import matplotlib.pyplot as plt
c, L = 1.0, 1.0
dx = L / 100
x = np.linspace(0, L, 101)
dt = 0.001
steps = 5000
u = np.zeros((101, steps))
u[:, 0] = np.sin(np.pi * x / L)
# First step approximation
u[:, 1] = u[:, 0]
for n in range(1, steps - 1):
for i in range(1, 100):
u[i, n + 1] = (
2 * u[i, n]
- u[i, n - 1]
+ (c * dt / dx)**2 * (u[i + 1, n] - 2 * u[i, n] + u[i - 1, n])
)
plt.plot(x, u[:, 1000])
plt.xlabel("Position")
plt.ylabel("Displacement")
plt.show()
Learning outcomes:
- Finite difference time-stepping for second-order PDEs.
- CFL condition and stability analysis.
- Wave reflection and standing waves.
- Visualization with animation or time snapshots.
Suggested extensions:
- Try different initial conditions such as a Gaussian wave packet.
- Add reflecting or absorbing boundaries.
- Compare the numerical solution with an analytical solution.
Intermediate Projects
These projects require a stronger background in numerical analysis, linear algebra, or physics. The code involves iterative solvers, adaptive methods, or more complex models.
4. Jacobi and Krylov Iteration for Linear Systems
Difficulty: Intermediate
Time: 4–6 weeks
What you will simulate: Iterative solutions to Ax = b using Jacobi, Gauss-Seidel, and Conjugate Gradient. This is the backbone of many PDE solvers.
Math model:
Ax = b
Here, A is usually sparse, and for many diffusion-style problems it is symmetric positive-definite.
Python stack: NumPy, SciPy, Matplotlib
Code template:
import numpy as np
import scipy.sparse as sp
import scipy.sparse.linalg as spla
def create_1d_laplacian_matrix(n, dx):
"""Create a 1D Laplacian matrix."""
main = 2.0 * np.ones(n)
off = -1.0 * np.ones(n - 1)
return sp.diags([off, main, off], [-1, 0, 1], format="csr") / dx**2
n = 100
dx = 0.01
A = create_1d_laplacian_matrix(n, dx)
b = np.ones(n)
# Jacobi iteration
x_jac = np.zeros(n)
D = A.diagonal()
for iteration in range(100):
r = b - A @ x_jac
x_jac = x_jac + r / D
# Compare with direct sparse solve
x_direct = spla.spsolve(A, b)
error = np.linalg.norm(x_direct - x_jac)
print(f"Jacobi error after 100 iterations: {error:.3e}")
Learning outcomes:
- Sparse matrix representation and operations.
- Iterative solver convergence analysis.
- Comparison of Jacobi, Gauss-Seidel, and Conjugate Gradient.
- Basic preconditioning concepts.
Why this project: Every PDE solver uses sparse linear systems internally. Understanding iterative methods at code level helps demystify tools such as FiPy, FEniCS, and OpenFOAM.
Suggested extensions:
- Add a diagonal preconditioner.
- Compare convergence rates on 2D and 3D grids.
- Implement a simple multigrid cycle.
5. Molecular Dynamics with Lennard-Jones Potential
Difficulty: Intermediate
Time: 4–8 weeks
What you will simulate: A gas or liquid of particles interacting through the Lennard-Jones potential. This project demonstrates the full cycle from physics model to numerical integration, data analysis, and visualization.
Math model:
V(r) = 4ε[(σ/r)¹² - (σ/r)⁶]
F = -∇V(r)
Typical integration methods include Velocity Verlet or leapfrog schemes.
Python stack: NumPy, Matplotlib, h5py
Code template:
import numpy as np
def lj_force(pos_i, pos_j, sigma=1.0, epsilon=1.0):
"""Compute Lennard-Jones force between two particles."""
r_vec = pos_j - pos_i
r = np.linalg.norm(r_vec)
if r == 0:
return np.zeros_like(r_vec)
inv_r = sigma / r
force_mag = 24 * epsilon * (2 * inv_r**12 - inv_r**6) / r
return force_mag * (r_vec / r)
def compute_forces(positions):
n = len(positions)
forces = np.zeros_like(positions)
for i in range(n):
for j in range(i + 1, n):
f = lj_force(positions[i], positions[j])
forces[i] += f
forces[j] -= f
return forces
Learning outcomes:
- Particle-based numerical integration.
- Periodic boundary conditions.
- Energy conservation monitoring.
- Radial distribution functions.
Why this project: Molecular dynamics is a gateway to high-performance scientific computing. Once you understand Lennard-Jones particles, you can move to complex potentials, coarse-graining, or GPU-accelerated MD.
Suggested extensions:
- Switch to GPU acceleration with
cupyornumba. - Study phase transitions by varying temperature.
- Calculate thermal conductivity with Green-Kubo relations.
6. Ising Model for 2D Magnetism
Difficulty: Intermediate
Time: 4–6 weeks
What you will simulate: The Ising model is one of the simplest models of magnetism and one of the most studied problems in statistical physics. It shows how local rules can produce macroscopic phase transitions.
Math model:
H = -J Σᵢⱼ sᵢsⱼ - h Σᵢ sᵢ
P(ΔE) = exp(-ΔE/kT)
Python stack: NumPy, Matplotlib, SciPy
Code template:
import numpy as np
def metropolis_step(grid, T):
"""Single Metropolis sweep on a 2D Ising grid."""
L = grid.shape[0]
for i in range(L):
for j in range(L):
site = grid[i, j]
neighbors = (
grid[(i - 1) % L, j]
+ grid[(i + 1) % L, j]
+ grid[i, (j - 1) % L]
+ grid[i, (j + 1) % L]
)
dE = 2 * site * neighbors
if dE < 0 or np.random.rand() < np.exp(-dE / T):
grid[i, j] = -site
return grid
Learning outcomes:
- Monte Carlo methods and the Metropolis algorithm.
- Phase transitions and critical phenomena.
- Energy minimization heuristics.
- Visualization of emergent patterns.
Why this project: The Ising model connects statistical physics, computational methods, and machine learning. It also has known reference behavior, which makes validation possible.
Suggested extensions:
- Calculate heat capacity and susceptibility near the critical temperature.
- Study different lattice geometries.
- Implement the Wolff or Swendsen-Wang cluster algorithm.
Advanced Projects
These projects require stronger numerical methods background, parallel computing experience, or specialized physics knowledge. They are suitable for thesis-level work or capstone projects.
7. FiPy-Based Diffusion Solver
Difficulty: Advanced
Time: 8–12 weeks
What you will simulate: A realistic diffusion problem using FiPy. This connects PDE concepts and finite volume discretization to production-grade scientific software.
Math model:
∂c/∂t = ∇·(D∇c) + S
This is a diffusion equation with source terms and boundary conditions such as Dirichlet, Neumann, or Robin conditions.
Python stack: FiPy, NumPy, Matplotlib
Code template:
from fipy import Grid2D, CellVariable, DiffusionTerm
mesh = Grid2D(nx=50, ny=50, dx=0.1, dy=0.1)
c = CellVariable(mesh=mesh, name="concentration", value=0.0)
c.constrain(1.0, mesh.facesLeft)
eq = DiffusionTerm(coeff=1.0) == 0
# Solve to steady state
eq.solve(var=c)
Learning outcomes:
- Finite volume discretization with FiPy.
- Handling Dirichlet, Neumann, and Robin boundary conditions.
- Mesh quality and convergence studies.
- Connecting analytical solutions to numerical results.
Why this project: If you want to work in computational science professionally, knowing how to use and extend a finite volume code like FiPy is valuable. This project combines mesh setup, term formulation, solver configuration, and post-processing.
Suggested extensions:
- Add reaction terms for reaction-diffusion systems or Turing patterns.
- Compare FiPy results against analytical benchmark solutions.
- Parallelize with FiPy’s MPI support.
8. Monte Carlo for Option Pricing
Difficulty: Advanced
Time: 6–10 weeks
What you will simulate: Monte Carlo methods in finance, including pricing European and American options using simulated stock price paths. This bridges computational science with applied mathematics and quantitative finance.
Math model:
dS = μS dt + σS dW
V = e^(-rT) E[max(S-K, 0)]
Python stack: NumPy, pandas, Matplotlib, scipy.stats
Code template:
import numpy as np
def monte_carlo_option(S0, K, r, sigma, T, num_paths=10000):
"""Price a European call option using Monte Carlo."""
z = np.random.randn(num_paths)
S_final = S0 * np.exp(
(r - 0.5 * sigma**2) * T + sigma * np.sqrt(T) * z
)
payoffs = np.maximum(S_final - K, 0)
price = np.exp(-r * T) * np.mean(payoffs)
stderr = np.exp(-r * T) * np.std(payoffs) / np.sqrt(num_paths)
return price, stderr
Learning outcomes:
- Stochastic simulation and path generation.
- Convergence analysis with sample size.
- Variance reduction techniques such as antithetic variates and control variates.
- American option pricing with least-squares Monte Carlo methods.
Why this project: Monte Carlo methods work in high-dimensional settings, which makes them useful in finance, materials science, quantum field theory, and uncertainty quantification.
Suggested extensions:
- Implement the Longstaff-Schwartz algorithm for American options.
- Study Greeks such as delta, gamma, and vega.
- Compare results against the Black-Scholes analytical solution.
9. Solidification and Phase-Field Simulation
Difficulty: Advanced
Time: 12–16 weeks
What you will simulate: The phase-field method is widely used in computational materials science for microstructure evolution, including grain growth, dendritic solidification, and precipitate formation.
Math model:
∂φ/∂t = -Γ [φ(1-φ)² + F'(φ) + λ∇φ·∇φ]
Here, φ is the phase field, Γ is mobility, and F(φ) is the double-well potential.
Python stack: FiPy, NumPy, Matplotlib
Code template:
from fipy import Grid2D, CellVariable, TransientTerm, DiffusionTerm
mesh = Grid2D(nx=100, ny=100, dx=1.0, dy=1.0)
phi = CellVariable(mesh=mesh, name="phase_field", value=0.0)
# Example starter equation structure:
# TransientTerm == diffusion + source-like phase evolution term
eq = TransientTerm(var=phi) == DiffusionTerm(coeff=1.0, var=phi)
for step in range(100):
eq.solve(var=phi, dt=0.01)
Learning outcomes:
- Phase-field formulation and double-well potentials.
- Interface width and mobility parameters.
- Coupling with diffusion equations.
- Comparison with analytical solidification solutions or literature benchmarks.
Why this project: Phase-field simulation is used in materials science research worldwide. It connects microstructure, thermodynamics, and numerical methods.
Suggested extensions:
- Couple the phase field with diffusion for solute trapping models.
- Study dendritic growth patterns under different undercooling conditions.
- Compare results against experimental micrographs from literature.
How to Choose Your Project
Not every project is right for every student. Use the framework below to pick a realistic starting point.
Match Your Background
| You Currently Know | Recommended Starting Project |
|---|---|
| Python basics, no numerical background | Heat equation |
| Python plus introductory numerical analysis | SIR model or wave equation |
| ODE/PDE course and linear algebra | Jacobi iteration or molecular dynamics |
| Statistical mechanics or advanced math | Ising model |
| Research or thesis-level goals | FiPy diffusion or phase-field simulation |
What Matters Most
- Mathematical prerequisites. Do not jump to phase-field simulation if you have not solved a PDE numerically yet.
- Programming comfort. If you are new to Python, start with the heat equation and build from there.
- Time horizon. A semester project needs clear scope. Pick something that can produce a meaningful result in 4–8 weeks.
- Career goals. Materials science points toward phase-field or molecular dynamics. Finance points toward Monte Carlo. Research software points toward FiPy or iterative solvers.
Common Mistakes Students Make
- Picking a project that is too ambitious. A full 3D phase-field solver in four weeks is not realistic. Scope it down to 2D with simple parameters.
- Skipping analytical solution comparison. Always compare numerical results against a known solution when possible.
- Ignoring the CFL condition. Many beginner simulations fail because the time step is too large.
- Not using version control. Git is not optional for a serious project. Commit regularly so you can recover from mistakes.
What Should You Skip?
Not all computational projects are equally useful for learning simulation. Avoid these unless you have a specific reason.
- Generic “hello world” simulations. If a project does not involve a PDE, conservation law, numerical solver, or stochastic model, it may not be a computational science project.
- Projects that require special hardware at the start. Do not begin with GPU molecular dynamics if you have not built CPU molecular dynamics first.
- Overly complex multi-physics coupling. Start with single-physics solvers. Multi-physics coupling is a research topic, not an ideal first student project.
Where to Find Reference Code
Several university courses and open-source projects provide useful reference implementations:
- University of Oslo Computational Physics — Course materials with project descriptions and solutions.
- AiiDA GSoC Projects — Student project ideas in computational materials science.
- FiPy Documentation — Official tutorials and examples for the finite volume library.
Use these resources as starting points, not endpoints. The real learning happens when you write and debug the code yourself.
Final Thoughts
The difference between reading about numerical methods and writing a simulation is enormous. You can read many PDE textbooks and still not understand what happens when a diffusion equation is discretized with a time step that is too large.
Pick one project, start coding, and iterate. A few weeks of debugging can teach more than months of passive lectures.
If you need help with a specific simulation problem, such as choosing the right solver, debugging a numerical instability, or scaling code to multiple processors, consider asking someone with experience. Good support can help you avoid common traps while still doing the work yourself.
Related Guides
- When to Use FEM, FVM, or FDM: A Practical Comparison for Beginners — Understanding discretization methods before you start coding.
- Mesh Quality and Convergence Studies: A Hands-On Guide — Making sure your grid does not ruin your simulation.
- Python Debugging for Scientific Code: From Print Statements to Profiling — Debugging strategies for numerical code.
- Computational Materials Science Frameworks: MOOSE vs PRISMS-PF vs OpenPhase — If you want to go beyond Python.