Every dot is one candidate reaction condition — a (temperature, catalyst loading) pair sampled from a dense grid across the process window. Two competing objectives are computed for each from smooth, chemically-motivated response functions (identical formulas to the 3D landscape version of this simulation):
Yield(T,C) = Ymax · exp(-((T-Topt)/σT)²) · (1-e^(-C/Ck)) · e^(-C/Cdecay)
E-factor(T,C) = a + b·C + c·(T/100)²
Domination: A ≻ B iff Yield(A) ≥ Yield(B) and E(A) ≤ E(B),
with at least one strict inequality.
Yield rises with catalyst loading up to a point then falls (catalyst-driven side reactions), and peaks at an optimum temperature. Waste (E-factor: kg waste per kg product) climbs steadily with both catalyst amount and temperature — so pushing yield up almost always pushes waste up too.
- Grid evaluation — the whole (T, C) window is sampled on a regular grid; every cell is scored on both objectives, from scratch, with no shortcuts.
- Non-dominated filtering — for every point, the engine checks all other evaluated points; if none of them dominates it, it belongs to the Pareto front (gold). This is an explicit O(n²) pairwise scan, not an approximation.
- Verification pass — after filtering, a second independent scan re-checks that no front point is dominated by anything in the full set. Any violation would be reported live in "Non-domination check" — it always reads OK because the filter is correct.
- Preference selection — the weight slider blends normalized yield and (inverted) waste into one score; the front point with the highest blended score is marked "selected best". It is only ever chosen from the verified front, never from a dominated point.
This is the same idea real self-driving labs use when yield alone is not the whole story: a chemist rarely wants the single highest-yielding recipe if it also means far more solvent waste — the Pareto front is the honest menu of trade-offs, and the weight slider is how much you personally care about each side of it.