Nilotpal Chakraborty
PhD candidate, Mechanical Engineering, Virginia Tech · PhD conferred May 2027
I build the numerical machinery that closed solvers do not provide. Most of my work happens inside other people's codes: special functions written from scratch because the solver ships no maths library, a per-particle state channel packed into the bits of a float because the API carries no state, an HLLC Riemann solver added to an open-source SPH library after working out why its surface tension broke.
My application domain is particle ingestion in gas-turbine compressors: 100M+ cell campaigns on HPC, in the Pratt & Whitney–Rolls-Royce Academic Alliance. The portable part is the machinery, not the domain.
Work-authorised on OPT with the STEM extension: up to three years, no day-one sponsorship required. Available June 2027.
What I do, in four pieces
Find what a solver gets wrong. Build what its API will not give you. Make the runs finish. Decide whether the answer can be trusted. One page each, and the code behind all of them is below.
I found defects in two solvers I did not write
An open-source SPH library whose surface-tension model fails above Re ≈ 10³, where the fluid particles do not disorder, they leave the domain: reported, and the maintainers' fix is now in a CMAME paper that acknowledges me. And a commercial solver that silently displaces particles crossing a stage interface, in all five geometries I have tested. Read →
I gave a commercial solver a feature its API does not have
Damage history had to survive a Lagrangian track across MPI ranks, but the solver carries one float per particle. So the history went inside the float. Read →
I made simulations possible that the group could not run before
Adding cores made the workstation slower. A scaling study across four machines separated what decides whether a job runs at all from what decides how fast, and took a month-long simulation to about a week. Then the same question about the output: 4.6% of the particles turned out to be writing 92% of the impacts. Read →
The model that wins on F1 is not the one I would deploy
A transformer beat the classical baseline on recall by fourteen points and introduced an error the baseline never made. On a second dataset the model ranking flips when the threshold moves. Deciding whether to believe a model is the part that transfers to surrogates. Read →
Code
Find what a solver gets wrong
-
sph-high-re-surface-tension
The instability above, in full: the diagnostic sequence, an HLLC Riemann solver, and the parameter studies underneath: a screening design, a one-factor-at-a-time sweep, a dissipation-limiter ladder, and a 2 × 2 factorial on Poiseuille flow. Video of all 29 runs.
-
cfx-interface-particle-shift
Striped erosion on a compressor rotor, traced to the solver displacing particles 4 mm circumferentially as they cross the stage interface. Eight hypotheses, seven killed by experiment, and an isolation test that decouples the particles from the flow entirely.
Build what its API will not give you
-
mantissa-state-channel
The solver's user API returns six values per particle impact and only one of them is still attached to the particle at the next blade. The damage history goes into the unused low bits of that one, costing 0.39% of the carrier, which across 385,170 mesh nodes is nearly three orders of magnitude finer than the median facet. Twelve tests, and figures generated by running the library.
Make the runs finish, and the output readable
-
cfx-cluster-scaling
The benchmark study behind the simulation-at-scale page. Standard advice is to minimise node count; measured, the run got 3.9× faster on sixteen nodes than one, because the workload is bound by I/O and memory throughput rather than compute. Timings as CSV, figures regenerated from them, and the sanitised job scripts.
-
cfx-particle-id-recovery
CFX writes one row per particle-wall impact and does not write which particle it belongs to. This recovers the identity by matching every impact against a 14 GB trajectory file on its position and velocity signature: 586,764 of 586,764 attributed, and the finding that 4.6% of the particles produce 92% of the impacts.
Numerical methods, measured against exact answers
-
cuda-poisson-sor
Red-black SOR for the Poisson pressure solve on an NVIDIA L40S, against a CPU baseline in the same language with the same compiler and flags. The reordering costs no convergence, the GPU overtakes one core between 65² and 129², and the kernel is bandwidth-bound at 89.6% of achievable DRAM throughput. It was moving 2.29× the bytes it needed; splitting the colours into separate arrays cut traffic to 1.48× and runtime by 1.55×, so the runtime is the traffic, to within one percent.
-
cfd-iterative-solvers
The companion study. Gauss-Seidel, SOR and ADI on a manufactured Poisson problem with a known exact solution, so error is measured rather than inferred from the residual. Observed order of accuracy 2.06; ADI reaches tolerance in about a quarter of the iterations SOR needs, at both resolutions.
-
Lid-driven-cavity
Incompressible Navier–Stokes on a staggered grid, fractional-step, validated against Ghia et al. (1982). It diverged at a time step below both the linear CFL and the viscous limit; the cause is a non-linear CFL condition on higher-order explicit integrators, and the solver now takes its step from that.
Elsewhere
Acknowledged in Zhang, Lourenço & Hu, Computer Methods in Applied Mechanics and Engineering 444 (2025). Also acknowledged in Estes et al., Aerospace 12 (2025) 1038, for contributions to the Virginia Tech modelling effort. Second author on a multiphase perfusion model in Experimental and Computational Multiphase Flow (2023). Three first-author manuscripts from the dissertation in preparation.
Pratt Fellowship, Virginia Tech College of Engineering (2022) · Summer Cunningham Fellowship, VT Graduate School (2026) · Mitacs Globalink Research Fellowship (2019) · Shastri Research Fellowship (2019).