Interests

Who I am, and the things I keep coming back to.

I’m a systems thinker and researcher in process systems engineering, focusing on optimization, machine learning, and AI for complex engineering systems. My interests lie in developing data-driven and decision-making methods that connect rigorous modeling with practical applications. I’m also interested in energy efficiency, industrial decarbonization, and sustainable energy systems, and alongside my research I work part-time in sustainability consulting, on energy efficiency assessments, emissions calculations and technical reporting.

I also enjoy building software, especially for iOS and macOS, and exploring ideas across engineering, computing, and product design. More broadly, I’m interested in becoming an interdisciplinary, architect-minded generalist who can connect different fields and turn ideas into well-designed systems.

Currently

  • Research

    M.Sc. research at Koç University, where catalysis meets machine learning and mathematical optimization.

    Since
  • Fellowship

    Fulbright PhD Scholarship candidate, for doctoral study in the United States from 2027.

    Since
  • Teaching

    Teaching assistant for CHBI 491 (Senior Design Project), leading sessions with senior teams on their capstone designs.

    Since

Process systems engineering

  • PSE
  • Modeling
  • Design
  • Control

Process systems engineering (opens in a new tab) looks at a plant as one connected system rather than a row of separate units: reactors, separators and heat exchangers, each with its own physics, tied together by streams, recycles and constraints. It asks for rigorous modeling and a practical decision at the same time.

Process flowsheet: feed, reactor, flash separator and recycle loopOrthographic process flow diagram drawn as sectioned equipment. Fresh feed (stream 1) meets the recycle in a static mixer, passes down through a fixed-bed catalytic reactor, is cooled in a single-pass shell-and-tube cooler against counter-current cooling water (supply in at the bottom, return out at the top), and is split in a flash drum. Liquid leaves as product (stream 6); vapour rises to a tee where a small purge (stream 7) leaves through a control valve and the rest is recompressed and recycled (stream 8) to the mixer.12345678CWRCWSLCRECYCLEFEEDREACTORPURGEFLASHPRODUCTCOOLER
Process flowsheet: feed, catalytic reactor, cooler and flash separator, with recycle compressor and purge.

Separation is often where most of the energy goes, and even the order of the cuts is a design decision. A four-component feed can be split by three simple columns in five different sequences; the direct sequence, which takes the lightest component off the top first, is only one of them.

Direct distillation sequence: A | BCD, B | CD, C | DOrthographic process flow diagram of a direct distillation sequence for a four-component mixture A, B, C, D (A lightest). Feed ABCD enters C-101, which takes A overhead and leaves BCD; C-102 takes B overhead and leaves CD; C-103 splits C from D. Each sieve-tray column is drawn in section with its total condenser (two-pass, cooling water on the tubes), reflux drum, inline reflux pump and kettle reboiler (steam in the U-bundle). Columns stand on a common base and narrow down the sequence as the feed shrinks (diameter ∝ √feed: 1, 0.75, 0.5); tray counts follow assumed relative volatilities α_AB 2.0, α_BC 3.0, α_CD 3.6 (Fenske, 99 % key recovery), feed trays follow Kirkbride: C-101 11 trays, feed above tray 6; C-102 7 trays, feed above tray 4; C-103 6 trays, feed above tray 4. Pressure falls from C-101 to C-103, so each bottoms product flows to the next column's feed tray by pressure difference, without a pump. C-101 CWRCWSE-101 V-101 P-101 STMCNDE-102 ABCDABCD C-102 CWRCWSE-103 V-102 P-102 STMCNDE-104 BCD C-103 CWRCWSE-105 V-103 P-103 STMCNDE-106 CD
Direct distillation sequence for a four-component feed: A | BCD, then B | CD, then C | D.

Underneath every model is hardware that moves fluids and holds a setpoint. A control loop ends in a valve: the controller computes an opening, and a quarter turn of a ball sets how much of the line is open.

Two-piece floating ball valve Isometric drawing of a two-piece floating ball valve, NPS 2 (DN50) class 150, flanged, 178 mm face to face, shown open: lever and ball bore parallel to the pipe. Open view: the front half of end cap, body, ball, seats and packing is cut away on the plane of the pipe and stem axes. One 49 mm bore runs straight through end cap, PTFE seats and ball (full bore), with the flow centreline. A tang on the stem engages a slot across the ball crown, parallel to the bore, so the ball floats against the downstream seat. Three packing rings and a gland follower fill the stuffing box in the neck. Six studs clamp end cap to body; two lie in the cut plane. Gland nut, lever and lever nut are exploded up the stem axis on a dashed guide; the lever has a bent stop tab. Closed view: the assembled valve, lever seated, its tab against a stop pin on the neck collar. END CAPPACKINGSTEMBALLPTFE SEATBODY GLAND NUT LEVER
Floating ball valve, DN50 class 150, half-sectioned; a quarter turn of the ball shuts the line.

Most of the plants I think about are energy systems in the end. The questions I keep returning to are where the heat goes, how much of it can be won back, and how to make the same product with less energy and fewer emissions.

Mathematical optimization

  • MILP
  • Superstructures
  • Multi-objective

Once a process can be written down, designing it becomes a question of choosing. Optimization makes the choice exact: variables, constraints and an objective, and a solver that searches a space far too large to try by hand. I like how much engineering judgment turns out to fit in that form.

The discrete choices are what make it hard. Whether to build a unit at all is a yes-or-no variable, so a design problem becomes a mixed-integer program, and the solver has to reason about a lattice of integer points instead of a smooth region.

MILP: a relaxation, an integer cut, and a proof Integer program: maximize cᵀx = 4x₁ + 3x₂ over integer x₁, x₂ subject to x₁ ≥ 1, x₂ ≥ 1, x₁ + x₂ ≥ 4, 3x₁ + x₂ ≤ 19, x₁ + 3x₂ ≤ 19 and x₁ ≤ 5.5. The hatched hexagon is the LP relaxation, with vertices (1, 3), (1, 6), (4.75, 4.75), (5.5, 2.5), (5.5, 1) and (3, 1); its hollow optimum is the vertex (4.75, 4.75) with bound 33.25. Solid dots are the 22 feasible integer points, faint dots are infeasible ones; the ringed integer optimum is (5, 4) with value 32. The dashed Chvátal–Gomory cut x₁ + x₂ ≤ 9, the sum of the two ≤ 19 rows divided by 4 and rounded down, passes through (4, 5) and (5, 4), keeps every feasible integer point and removes the dithered wedge that holds the LP optimum. The faint dashed iso-objective line cᵀx = 33.25 touches the relaxation only at the LP optimum; the objective arrow c = (4, 3) stands perpendicular to it and points toward increasing cᵀx. Branch and bound on x₁ = 4.75: the child x₁ ≤ 4 has LP optimum (4, 5) with value 31, the child x₁ ≥ 5 has LP optimum (5, 4) with value 32; both are integral, so 32 is optimal and the gap to 33.25 is closed. x₁ x₂ cTx CUTx₁+x₂≤9 FEASIBLEREGION LP OPTIMUM INTEGEROPTIMUM BRANCH &BOUND 33.25 x₁ ≤ 4 x₁ ≥ 5 31 (4,5) 32 (5,4)
Mixed-integer program: integer lattice, LP relaxation, a valid cut and the branch-and-bound tree.

A superstructure takes that to the whole flowsheet. It holds every candidate technology and every link between them, and the solver keeps only the ones worth building.

Power-to-X superstructure: candidate technologies and the selected designOrthographic superstructure for a hydrogen-based water-energy-food system. Resources (solar, wind, seawater) feed candidate technologies (battery, PEM electrolyzer, reverse-osmosis desalination, hydrogen storage tank, Haber-Bosch ammonia synthesis, methanation) that supply products (power, hydrogen, ammonia, methane, water). Each technology carries a binary build decision y in {0,1}. The drawn selection (solid, y=1) is electrolyzer, desalination, storage and Haber-Bosch; battery and methanation stay candidates (dashed, y=0). Nitrogen and carbon dioxide enter as battery-limit feeds. Every selected unit has its inputs supplied and its outputs consumed.H₂OH₂N₂CO₂011110POWERH₂NH₃CH₄WATERRESOURCESTECHNOLOGIESPRODUCTSELECTROLYZERSTORAGEHABER–BOSCHMETHANATIONDESALINATION10SELECTED (y=1)CANDIDATE (y=0)
Superstructure optimization for a Power-to-X system: every candidate technology and link, with the selected design (y = 1) drawn solid.

Real objectives also pull against each other. Cost and emissions rarely fall together, so the useful answer is the whole curve of trade-offs, and a decision maker picks a point on it.

Pareto front: cost against CO₂, solved by ε-constraint Bi-objective design trade-off, both objectives minimised: total annualised cost c in M€/a (horizontal) against CO₂ emissions e in kt/a (vertical). The attainable set is bounded by the convex frontier e = -4 + 434/(c − 8.5) for c from 12 to 24. 11 efficient designs lie on it, evenly spaced along the drawn curve; 210 seeded candidate designs (small dots) lie above it inside the ideal–nadir box. A non-dominated filter over all 221 designs returns exactly the 11 efficient designs (round markers on the 2-unit Pareto front); every small dot is dominated by at least one of them. Axis ticks: cost 12 to 24 M€/a in steps of 3, CO₂ at 50, 75, 100 and 120 kt/a. Utopia point (12, 24) and nadir point (24, 120) span the dashed box. Dashed ε-lines show the ε-constraint method, min c subject to e ≤ ε, at ε = 89.27, 62.42, 43.18, 31.35 kt/a; each touches the front at its optimum, c = 13.15, 15.03, 17.7, 20.78 M€/a, where the constraint is active. The hatched quadrant is the region dominated by design A (15.03, 62.42). Inset: design A against design B (20.78, 31.35) as pixel bars, cost and CO₂, each metric on its own zero-based scale. 12151821245075100120COST M€/aCO₂ kt/a ABABAB COSTM€/aCO₂kt/a15.020.86231 PARETO FRONT ε-CONSTRAINT UTOPIA NADIR DOMINATED
Cost versus emissions: candidate designs, the Pareto front, and solutions found with the ε-constraint method.

Stochastic models

  • Uncertainty
  • Two-stage programs
  • MPC

Optimization quietly assumes the numbers are known. They rarely are: renewable supply moves by the hour, prices and demand drift, and a plant designed for the average day can fail on the real one. Stochastic models put that randomness into the problem itself.

My favourite form is the two-stage program. Fix the design now, let the operation adapt once each scenario plays out, and optimize the expected cost over all of them together. The value of doing so can be measured as the gap between the stochastic answer and the deterministic one. It was the core of my undergraduate research.

Two-stage stochastic program: scenario tree with recourse Two-stage stochastic program min cᵀx + Σ p_s Q(x, ξ_s), drawn as a scenario tree. The first-stage decision x (installed capacity: PV 2.5 MW, wind 1.5 MW, battery 2 MWh, shown as pixel bars in a double-rimmed node) is a single node shared by every scenario, which is non-anticipativity. It fans out to four renewable-availability scenarios with probabilities sunny 0.35, windy 0.30, cloudy 0.25, calm 0.10 (sum 1.00). Each scenario card is a 24-hour sparkline of available renewable output (PV plus wind, MW) in 0.4 MW pixel steps, with the flat 1 MW load as a dotted line. The recourse y_s is the hourly dispatch: surplus charges the battery (90% efficient), deficits discharge it, and the rest is imported at 100 EUR/MWh. Q(x, ξ_s) is that import cost in thousand EUR per day (0.82, 0.23, 0.65, 1.73), and the probability-weighted bracket gives E[Q(x, ξ)] = 0.69. FIRST STAGE xPV2.5 MWWIND1.5 MWBATT2.0 MWh 0.350.300.250.10Σ 1.00ps SUNNYWINDYCLOUDYCALMLOAD 1.0 MWSCENARIOS ξs 0.820.230.651.73RECOURSE ysQ(x,ξs) E[Q(x,ξ)]= 0.69 k€minxcTx+Σs ps Q(x,ξs)
Two-stage stochastic program: one first-stage design x, scenarios ξₛ with probabilities pₛ, recourse yₛ, and the expected recourse cost.

The same idea carries into control. Model predictive control solves a small optimization at every step over a moving horizon, applies only the first move, and plans again once new measurements arrive, which is how it absorbs disturbances it could not predict.

Model predictive control: the receding horizon Two stacked time plots split by a vertical line at the current sample k. Upper plot: the measured output y of the first-order plant y[t+1] = 0.8 y[t] + 0.2 u[t], steady at 0.2 until the set-point steps to 1 at k-3, then rising; to the right of k, the dashed reference r = 1 and the predicted output y-hat(k+i|k) over a prediction horizon of Np = 10 samples, which is the model rolled out on the planned inputs. Lower plot: past inputs as zero-order-hold bars, then the plan from the quadratic cost sum (y-hat - r)^2 + 8 sum du^2 with control horizon Nc = 4: four shrinking upward moves, held constant afterwards. Only the first move, u(k), is applied; at the next sample the window shifts one step and the problem is solved again. y u t PASTPREDICTION HORIZON NCONTROL HORIZON NNOW (k)REFERENCE rPREDICTED ŷAPPLIED u(k)
Model predictive control: the prediction and control horizons at time k, the predicted output, and the first planned move that is applied.

Machine learning

  • ML
  • Deep learning
  • PyTorch

I came to machine learning from the computer engineering half of my degree and stayed because it changes the modeling question. Where a first-principles model is weak or too slow, a learned one can fill the gap, as long as it respects the physics and the constraints around it. Underneath almost all of it is one loop: follow the gradient of a loss downhill, a small step at a time.

Gradient descent on a loss landscape Exploded isometric view. A quadratic loss surface L(θ), drawn as a mesh with banded level sets, floats above the parameter space θ, where the same level sets appear rasterised into pixel-stepped dither bands. Starting at θ₀, gradient descent takes the exact updates θₖ₊₁ = θₖ − η∇L(θₖ): each step runs opposite the gradient ∇L(θ₀), drawn perpendicular to the level set through θ₀, zig-zagging across the steep valley walls and converging into the minimum. ΔL(θ₀)θ₀ηLOSSSURFACEMINIMUMPARAMETERSPACE θHILO
Gradient descent on a quadratic loss surface: iterates θₖ₊₁ = θₖ − η∇L(θₖ) converging to the minimum.

The simplest learners are still the clearest way to see what a model does. k-nearest neighbours has no training step at all: a new point takes the vote of the k closest examples, and the decision boundary is simply where that vote changes.

k-nearest-neighbour classification A two-feature plane, x₁ and x₂ from 0 to 10 on equal scales, with 42 labelled training samples in three classes (A filled, B open, C ringed dot; A: 14 draws from a normal distribution centred at (2.9, 6.6), sd 1.15; B: 14 draws from a normal distribution centred at (6.8, 6.9), sd 1.15; C: 14 draws from a normal distribution centred at (5, 2.9), sd 1.2; seed 20261007). The query point (7.5, 4.4) is joined to its k = 5 nearest samples by Euclidean distance; the circle has radius d₅ = 1.85, the distance to the 5th neighbour. Majority vote A 0, B 3, C 2: predicted class B (k = 1 would predict C). Dither fills the region each class wins under 5-NN (B is left blank); its edge and the ink line are the decision boundary, traced to within 1 plotted unit. Distance ties go to the lower sample index, vote ties to the tied class with the nearest member. 00224466881010x₂x₁ NEIGHBOURHOOD DECISION BOUNDARY QUERYCLASS ACLASS BCLASS C QUERY(7.50, 4.40)VOTEk = 5 CLASS A0CLASS B3CLASS C2 PREDICTIONCLASS B NEARESTd 10.4721.3131.6341.8351.85 r = d₅1.85
k-nearest-neighbour classification: three classes, the decision regions for k = 5, and one query’s vote.

Knowing how sure a model is matters as much as the prediction, which is where learning meets the stochastic side again. Conformal prediction wraps any forecaster in an interval with guaranteed coverage, built from nothing but its past errors.

Split-conformal prediction interval on a 24-hour demand forecast The last 36 hours of hourly electricity demand in GW (synthetic, seeded daily cycle with noise) end at a vertical NOW line. A seasonal-profile model, the mean of the same hour over the previous 7 days, forecasts the next 24 hours as a heavy line. Around it, a split-conformal 90% interval is drawn as grid-snapped pixel cells, one column per forecast hour, under its exact vector edges: the band is the forecast plus or minus q-hat. To the right, a pixel histogram of 336 calibration residuals |y − ŷ| shares the same vertical scale; q-hat = 1.60 GW, the 304th smallest of the 336 residuals (k = ceil((n+1)(1−α)), α = 0.1), is a horizontal line that meets the band's upper edge, and a dimension bracket shows that the band half-width equals q-hat. The actual next-day demand is a faint dashed line; 22 of 24 hours fall inside the band, shown by a coverage strip under the time axis. GW303540−36 H−24 H−12 HCOVERAGE22/24 = 92%HISTORYNOWACTUALFORECAST ŷ90% INTERVAL|y−ŷ|qqq = 1.60 GWCALIBRATIONRESIDUALS
Day-ahead forecast with a split-conformal interval: the band half-width is the calibrated quantile q̂ of past residuals.

Language models

  • LLMs
  • Transformers
  • Agents

Language models are the newest piece, and the one I use every day. Inside, a transformer is attention repeated many times: each token looks back at the ones before it and takes a weighted mix of what it finds.

One causal self-attention head Seven tokens t₁ to t₇ each look up a 6-dimensional embedding, drawn as a strip of pixels. Three learned projections W_Q, W_K and W_V map every embedding to a 4-dimensional query, key and value. The queries sit beside the attention matrix and the keys stand above it as columns, so cell (i, j) holds softmax over keys of q_i·k_j/√d with d = 4. A causal mask removes every key that comes after its query, so the hatched upper triangle is zero and each row sums to one. One query row is highlighted; its weights a_i, turned on their side next to the values, set the strength of the lines that sum the values into the output vector z_i. The highlight sweeps down the rows one query at a time. t₁t₂t₃t₄t₅t₆t₇TOKENS EMBEDDINGS WKQKTVWQWV CAUSAL MASKSOFTMAX(QKT/√d) ai OUTPUT z01
One causal self-attention head: queries, keys and values, the softmax(QKᵀ/√d) weights with the causal mask, and one output as a weighted sum.

What interests me most is putting them to work on science, reading papers at scale and turning text into data that other models can use.

Building tools

  • Swift
  • macOS
  • iOS
  • Product design

Outside research I build the software I want to use, mostly for the Mac and iPhone in Swift, and I care as much about how it feels as about what it does.

Right now that means SnapLayouts, Seemantic and Quotlas. They are on the work page.

Connecting fields

  • Systems thinking
  • Generalist

I studied chemical and biological engineering alongside computer engineering, and I want to be an interdisciplinary, architect-minded generalist who connects fields and turns ideas into well-designed systems.

My degree tracks were Energy and Process Systems Engineering on one side and Artificial Intelligence on the other, and this page sits between the two.

Every drawing, in the Gallery