Nilotpal Chakraborty
PhD candidate, Mechanical Engineering, Virginia Tech · PhD conferred May 2027
I work out what a simulation result is entitled to claim, and build whatever is missing to get it. Most of that happens inside other people’s codes. Finding the defect that nothing reports. Writing the special functions because the solver ships no maths library. Packing a per-particle state channel into the bits of a float because the API carries no state.
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 five pieces
Find what a solver gets wrong. Build what its API will not give you. Decide whether something faster can replace it. 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 five defects in code I did not write, and none of them crashed
A surface-tension model that fails above Re ≈ 10³, reported, and the maintainers' fix is now in a CMAME paper that acknowledges me. A commercial solver that silently displaces particles crossing a stage interface. The same solver handing a routine one reference frame and reading its answer in another. An undocumented limit that truncates a cascade after three generations, found by reconstructing lineage. And a constant disagreeing with its own derivation. Read →
Deciding whether a reduced-order model can be trusted
I verified a fast model against the simulation it is meant to replace. The derivation held, one constant in the code was wrong, it beats the published relation it extends by a factor of seventeen, and it stops working at a diameter I could predict two independent ways. The hardest test was the one nobody had run. 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 →
Five times a computable number turned out to mean nothing
Counting rows instead of events. A metric set by an arbitrary cutoff rather than by physics, moving by a factor of 22 while the quantity that mattered moved 2%. The same symbol meaning two things, worth a 2.7-fold difference in what an experiment would be fed. A value censored by its own definition. And one of my own scripts printing something it was not entitled to print. 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-wall-film-breakage
A wall-film routine is handed an impact velocity relative to the wall and its answer is read as absolute, so on a rotor every fragment launches short. Proved with one particle, one impact and no model at all, both coefficients hardcoded at 0.500. Plus an undocumented parameter that stops the cascade after three generations: at generation three no particle ever broke, although 3,773 impacts carried enough energy.
-
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). A first-author manuscript on particle rebound and breakage modelling is under review, with further dissertation manuscripts and two second-author submissions to ASME Turbo Expo 2027 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).