CFD & computational engineering · Portfolio 2026

Computational engineering, from equations to simulation.

I’m Susheel, a fourth-year Mechanical Engineering student at GITAM University. In summer 2026 I completed a research fellowship in the Department of Aerospace Engineering at IIT Madras. My work focuses on numerical methods and simulation: a finite-volume flow solver and an early-stage lattice-Boltzmann module that I’m writing myself, a physics-informed neural network benchmarked against an exact solution, and structural FEA of a roll cage.

  1. EducationGITAM UniversityB.Tech Mechanical Engineering · 4th year
  2. ResearchIIT MadrasSummer research fellow · Aerospace Engineering · 2026
4
load cases analysed on the roll cage
1.39 mm
largest peak deformation (rollover case)
2.7×10−3
PINN max abs. error vs exact, iteration 8000
3
projects, one still ongoing
Roll cage · rollover case · peak total deformation 1.387 mm (Ansys Mechanical)
01

Roll cage: structural analysis

  • Static structural FEA
  • Ansys Mechanical 2026 R1
  • 4 load cases
  • Tetrahedral mesh

A Baja roll cage modelled as a tubular frame and meshed for finite-element analysis. Front impact, side impact, rear impact and rollover each run as their own static-structural analysis on the same model, with their own applied force and fixed support. Choose a case to see its deformation field.

Peak deformation
0.0488 mm
Mean deformation
1.72×10−3 mm
Peak occurs at
Front nose tube
Rest of frame
Near zero (dark blue)
How to read the scale. The contour legend in each image is true displacement in millimetres. The deformed shape itself is magnified by Ansys’ auto-scale so that sub-millimetre movement is visible, so the geometry looks far more distorted than it really is. The scale bar under each model is 0–1000 mm.

Results at a glance

Load casePeak (mm)Mean (mm)Peak, relative to largest
0.0487781.7203×10⁻³
0.832374.2622×10⁻²
0.556342.4314×10⁻²
1.38697.7132×10⁻²

Bars are drawn on a linear scale from zero. Each case has its own applied force and support, so read the bars within a case rather than as a ranking of severity.

What I set up

  • One model, four analyses. The same geometry, materials and mesh feed four static-structural systems.
  • Per-case boundary conditions. Each load case carries its own force and fixed support.
  • Results ready to review. Total deformation, equivalent stress and a stress tool are set up for every case.
  • Local response. In all four cases the movement stays in the loaded tubes while the rest of the frame stays near zero.
02

PINN for the 1D heat equation

  • Physics-informed neural network
  • PyTorch
  • Benchmarked against exact solution

A small neural network learns the temperature field u(x, t) from the physics alone: the PDE residual, the initial condition and the boundary conditions are the only training signal, with no measured data. Because this problem has a closed-form answer, I can score the network exactly.

The problem

Governing equation (α = 0.1)∂u/∂t = α · ∂²u/∂x²
Initial condition, 0 ≤ x ≤ 1u(x, 0) = sin(πx)
Boundary conditions, t ≥ 0u(0, t) = u(1, t) = 0
Exact solution (used only for scoring)u(x, t) = e−απ²t · sin(πx)

The sine profile just decays: the peak falls from 1 at t = 0 to e−0.1π² ≈ 0.373 at t = 1.

The setup

  • Network: fully connected, inputs (x, t), one output u, three hidden layers of 32 tanh units (2,241 trainable parameters).
  • Loss: equal-weight sum of three mean-squared terms: PDE residual, initial condition, boundary conditions.
  • Derivatives: ∂u/∂t and ∂²u/∂x² come from automatic differentiation, not finite differences.
  • Training points: 30 × 30 = 900 collocation points in the domain, plus 30 points each on the two boundaries and the initial line.
  • Optimiser: Adam, learning rate 10−3, 10,001 iterations, fixed seed.
  • Scoring: 50 × 50 test grid on [0, 1]², compared with the exact solution.

Training explorer

8000
Total loss
–
Max |error|
–
PINN output range
–
Exact range
0 … 0.9995

Each error panel has its own colour scale. The colourbar limits (and the ×10⁻³ or ×10⁻² multiplier above it) change from snapshot to snapshot, so compare numbers, not colours. The solution panels share the same 0 to 1 colour mapping.

Loss and error, logged every 2000 iterations

Total lossMax |error| vs exact

All snapshots

IterationTotal lossMax |error|

Loss fell about 76,000× and max error about 380× between iteration 0 and 8000. It did not fall monotonically: iteration 6000 shows a transient rise before training recovered. Snapshots after iteration 8000 are not shown here.

03

My own CFD solvers: FVM + LBM

  • Ongoing · my own solvers
  • Finite-volume CFD
  • Lattice-Boltzmann (early stage)
  • Python · SciPy

This section is about my own solvers, written from first principles so I understand every term in the numerics. The two-dimensional staggered-grid finite-volume solver for cylinder flow is implemented. The D2Q9 lattice-Boltzmann module is at an early stage, with the grid and BGK equilibrium initialisation done so far. Neither has been verified yet, so this section shows work in progress and no final results. Fluid–structure coupling remains a future goal. My IIT Madras fellowship work with the lab’s HORFID solver is separate and is described in the next section.

Schematic of my own solver’s set-up, not solver output: two cylinders side by side across the flow, centre spacing L = 3D, drawn as the staircase mask the solver applies on a Cartesian grid. The cylinder spacing is to scale; cell counts are illustrative.

My own solvers · implementation status

  • Implemented: 2D staggered-grid finite-volume solver for flow past a circular cylinder (code excerpt below).
  • Implemented: forces on the body recorded every step through a momentum-forcing approach.
  • Early stage: D2Q9 lattice-Boltzmann module. Implemented so far: the grid class and BGK equilibrium initialisation. Not yet shown here: a collision–streaming loop, boundary treatment or any validated result.

My own solvers · verification: pending work

None of the checks below has been done yet.

  • Quantitative divergence and residual checks on the projection step.
  • Grid and time-step refinement study.
  • Benchmark comparison and error analysis against a reference.
  • FVM–LBM comparison under matched conditions.
  • Longer-term goal: fluid–structure coupling. Not complete yet.

How my finite-volume solver works

  • Grid: staggered layout, velocities on cell faces and pressure at cell centres.
  • Time stepping: fractional-step projection. Explicit predictor, pressure-Poisson solve, velocity correction.
  • Convection / diffusion: first-order upwind and central differencing. Stable but diffusive, a trade-off noted in the code.
  • Pressure solve: sparse operator factorised once with SciPy’s LU, with one pinned reference cell to remove the null space.
  • Cylinder: staircase no-slip mask on the Cartesian grid. Stable time step from convective and diffusive CFL limits.

The projection step, from solver.py

solver.py · excerptFVMCylinderSolver
def _pressure_correction(self, u_star, v_star, dt):
    g = self.g
    div = (u_star[1:, :] - u_star[:-1, :]) / g.dx + (v_star[:, 1:] - v_star[:, :-1]) / g.dy
    rhs = (self.rho / dt) * div.flatten(order="C")
    rhs[(g.nx - 1) * g.ny + 0] = 0.0  # match pinned cell
    p = self._lu.solve(rhs).reshape(g.nx, g.ny, order="C")

    u = u_star.copy()
    v = v_star.copy()
    u[1:-1, :] -= dt / self.rho * (p[1:, :] - p[:-1, :]) / g.dx
    v[:, 1:-1] -= dt / self.rho * (p[:, 1:] - p[:, :-1]) / g.dy
    u, v = self._apply_velocity_bcs(u, v)
    return u, v, p

def step(self, dt):
    u_star, v_star = self._predictor(dt)
    u, v, p = self._pressure_correction(u_star, v_star, dt)
    self._record_force(u_star, v_star, dt)
    self.g.u, self.g.v, self.g.p = u, v, p
    self.t += dt
See the momentum predictor (u-component)
# ---------- u-momentum, interior faces i=1..nx-1 ----------
ui = u[1:-1, :]                       # (nx-1, ny)
uE, uW = u[2:, :], u[:-2, :]
uN, uS = up[1:-1, 2:], up[1:-1, :-2]

dudx_c = (uE - uW) / (2 * dx)
dudy_c = (uN - uS) / (2 * dy)
# upwind correction using local sign of velocity
dudx_up = np.where(ui > 0, (ui - uW) / dx, (uE - ui) / dx)
v_at_u = 0.25 * (vp[1:-2, :-1] + vp[2:-1, :-1] + vp[1:-2, 1:] + vp[2:-1, 1:])
dudy_up = np.where(v_at_u > 0, (ui - uS) / dy, (uN - ui) / dy)

conv_u = ui * dudx_up + v_at_u * dudy_up
lap_u = (uE - 2 * ui + uW) / dx**2 + (uN - 2 * ui + uS) / dy**2

u_star = u.copy()
u_star[1:-1, :] = ui + dt * (-conv_u + nu * lap_u)
04

IIT Madras research fellowship

  • Completed · summer 2026
  • IASc–INSA–NASI fellowship
  • Potential flow
  • Python
  • ParaView

An eight-week summer research fellowship in the Department of Aerospace Engineering, under Dr. Bharath Govindarajan, on flow past two side-by-side circular cylinders. It is separate from my own solvers above: HORFID is the lab’s in-house CFD code and is not mine, while the analytical model below is my own Python code.

Analytical model · my code

  • Method: incompressible potential flow past two side-by-side cylinders in bipolar coordinates, following Alassar and El-Gebeily.
  • Implementation: modular Python covering the bipolar parameters, coordinate transform, stream function, velocities by central differences, surface pressure coefficient, and drag and lift by trapezoidal integration.
  • Check: the Cp distribution was compared with published results.
  • Limits: inviscid, so no boundary layers, separation or vortex shedding.

HORFID simulations · the lab’s solver, not mine

  • Cases: six angles of attack, 15° to 90°, with identical settings.
  • Set-up: Re = 100, Ma = 0.1, Pr = 0.72, 16D × 16D domain, one structured Pointwise mesh (CGNS) reused for every case.
  • My role: I ran the cases and post-processed drag, lift and velocity-magnitude contours in ParaView.
  • Not shown on this page: the coefficient values and contour figures.

Experimental data

  • Trisonica ultrasonic anemometer: processed the raw measurements in Python, with filtering, statistics and comparison against reference data.
05

How I work

The same loop shows up in every project above.

Frame the problem

Pin down the geometry, loads, constraints and what “good” looks like before touching a solver.

Evidence: four defined load cases

Build the model

Geometry, mesh, equations and boundary conditions, set up once and reused cleanly.

Evidence: one model, four analyses

Check against a reference

Compare with an exact solution or a known behaviour so the number can be trusted.

Evidence: PINN scored against the exact answer

Show it honestly

Label scales, flag limitations and say what isn’t finished yet.

Evidence: scale notes and the unfinished CFD solver
06

Skills & tools

Only what the projects above actually use.

Analysis

  • Ansys Mechanical (static structural)
  • Finite-element meshing
  • Pointwise (structured CFD meshing)
  • Result post-processing

Methods

  • Finite volume
  • Projection methods
  • Lattice-Boltzmann (early stage)
  • PINNs

Code

  • Python
  • NumPy / SciPy
  • Matplotlib
  • PyTorch
  • C++

Communication

  • ParaView
  • LaTeX reports
  • Technical figures
07

Contact

Interested in CFD, numerical methods and simulation engineering internships. The quickest way to reach me is email.

Email me → susheelpeesapati@gmail.com