KomuraSoft LLC / Learn
Home Courses Understand the Haber–Bosch Process with Diagrams and Exercises Simulator and minimal model — move the parameters and build intuition

Chapter 6 · 4 questions · Graded in-browser · Saved locally

Simulator and minimal model — move the parameters and build intuition

Using a simplified teaching model, visualize how temperature, pressure, catalyst activity, purge rate, and inert contamination affect each of the indicators.

This page is readable without JavaScript, but the simulator and grading will not run.

Comprehension check for this chapter

0 / 4 correct. Results are saved only in this browser's localStorage.

First, move the five parameters one at a time

The simulator in this chapter reduces temperature, pressure, catalyst activity, purge rate, and inert contamination into a simplified teaching model. The goal is not rigorous design calculation; it is to visually separate which operating parameter affects which indicator.

  • Temperature: Lower is better for equilibrium, but the rate tends to drop.
  • Pressure: Higher favors the equilibrium.
  • Catalyst activity: Primarily affects the rate side.
  • Purge rate: Too low and inerts cannot escape.
  • Inert contamination: Eats into the partial pressures inside the loop and drops the apparent performance.

HB101 simulator

Move the conditions and see where they land

This is not a real-plant calculation; it is a teaching-purpose model for getting a feel for which conditions push equilibrium, rate, and loop health.

Equilibrium favorability
0%
Rate score
0%
Estimated single-pass conversion
0%
Recycle load
0%
Inert-accumulation risk
0%
How to read it

Rather than focus on any one metric, the trick is to read equilibrium, rate, recycle, and purge as a balance.

The JavaScript of the teaching model

The teaching-side code is also written short, without hiding the formulas or assumptions. Values outside the input ranges are not silently corrected — they stop with a RangeError.

About the coefficients

The numeric constants in the code below (0.18, 0.52, 0.30, etc.) are not derived from real-plant measurements or strict thermodynamic / kinetic equations. They are teaching-purpose coefficients hand-picked so that the qualitative relationships between conditions and indicators that this course keeps repeating are reproduced as 0–1 scores. For example, the ratio between 0.52 * temperatureBonus and 0.30 * pressureBonus expresses the relative feel that "temperature has a slightly stronger effect than pressure," and the base value 0.18 represents "a minimum floor that does not drop fully to zero under any condition." Never use these numbers for real-plant design; read them only as a model that connects the body text to the visible numbers.

function assertFiniteInRange(name, value, min, max) {
  if (!Number.isFinite(value) || value < min || value > max) {
    throw new RangeError(`${name} must be a finite number in [${min}, ${max}]`);
  }
}

function clamp01(value) {
  if (!Number.isFinite(value)) {
    throw new RangeError("value must be finite");
  }
  return Math.min(1, Math.max(0, value));
}

// Equilibrium favorability: scores the Chapter 3 relationship that
// "lower temperature and higher pressure favor the NH3 side" as 0..1.
function equilibriumFavorability(temperatureC, pressureBar) {
  assertFiniteInRange("temperatureC", temperatureC, 350, 550);
  assertFiniteInRange("pressureBar", pressureBar, 80, 280);

  // Bonus for being below 520 degC (0..1). 170 scales the 350-520 degC span.
  const temperatureBonus = clamp01((520 - temperatureC) / 170);
  // Bonus for being above 80 bar (0..1). 170 scales the 80-250 bar span.
  const pressureBonus = clamp01((pressureBar - 80) / 170);
  // 0.18 = floor, 0.52 = temperature contribution, 0.30 = pressure contribution.
  // Their ratio reflects the qualitative claim that temperature has a slightly
  // stronger effect than pressure, as a teaching choice.
  return clamp01(0.18 + 0.52 * temperatureBonus + 0.30 * pressureBonus);
}

// Rate score: scores the Chapter 4 relationship that
// "higher temperature and higher activity make the reaction faster" as 0..1.
function rateScore(temperatureC, catalystActivityPct) {
  assertFiniteInRange("temperatureC", temperatureC, 350, 550);
  assertFiniteInRange("catalystActivityPct", catalystActivityPct, 40, 120);

  // From 360 degC up, the drive grows with temperature (0..1).
  const temperatureDrive = clamp01((temperatureC - 360) / 140);
  const activity = catalystActivityPct / 100;
  // 0.12 = floor, 0.78 = product of temperature x activity (so "both must be
  // present together" before the rate goes up).
  return clamp01(0.12 + 0.78 * temperatureDrive * activity);
}

// Inert accumulation risk: scores the Chapter 5 relationship that
// "high inert load + low purge" raises risk, as 0..1.
function inertRisk(purgePct, inertPct) {
  assertFiniteInRange("purgePct", purgePct, 0.5, 8);
  assertFiniteInRange("inertPct", inertPct, 0, 8);

  // Below 4.5%, lowPurge climbs.
  const lowPurge = clamp01((4.5 - purgePct) / 4);
  const inertLoad = clamp01(inertPct / 8);
  // 0.04 = floor, 0.64 = inert contamination contribution (primary driver),
  // 0.22 = low-purge contribution (secondary).
  return clamp01(0.04 + 0.64 * inertLoad + 0.22 * lowPurge);
}

// Estimated single-pass (one-through) conversion.
function estimateSinglePassConversion(temperatureC, pressureBar, catalystActivityPct, purgePct, inertPct) {
  const equilibrium = equilibriumFavorability(temperatureC, pressureBar);
  const rate = rateScore(temperatureC, catalystActivityPct);
  const risk = inertRisk(purgePct, inertPct);
  // Symmetric design around 4% purge:
  //   - increasing purge helps inerts leave, slightly raising conversion (max +0.02);
  //   - increasing purge too far loses feed H2, slightly lowering effective conversion (max -0.02).
  // The result is an apparent "sweet spot" near 4% purge.
  const purgeBenefit = clamp01(purgePct / 4) * 0.02;
  const purgeLoss = clamp01((purgePct - 4) / 4) * 0.02;
  // 0.05 = base conversion, 0.23 = equilibrium x rate contribution
  // (product so "both must be present"), -0.05 = penalty from inert risk.
  const raw = 0.05 + 0.23 * equilibrium * rate - 0.05 * risk + purgeBenefit - purgeLoss;
  // Clip output to 3..28% as a sanity guard for a teaching model.
  return Math.min(0.28, Math.max(0.03, raw));
}

We split equilibriumFavorability and rateScore first, then layer inertRisk on top to produce estimateSinglePassConversion. For a teaching codebase, having it decomposed at this level makes it easier to see "which part of the explanation corresponds to which piece of the code."

How to use this simulator

The recommended approach is to press "Textbook" first to get a baseline, then change only temperature, only pressure, or only catalyst activity. Moving multiple parameters at once makes it hard to tell which change produced which effect.

Note

The numbers here are not real-plant guaranteed values or safety-design values. They are from a scaled, intuition-oriented teaching model.

Comprehension check for this chapter

Practice 26–29

Check how to read the simulator and the code policy of the minimal model.

Chapter 6 / Practice 1

Q26. When you press the "Catalyst degraded" preset in the simulator, which indicator drops most directly?

Unanswered
Chapter 6 / Practice 2

Q27. If you hold temperature constant and raise only pressure in the simulator, which is most directly easier to improve?

Unanswered
Chapter 6 / Practice 3

Q28. If inert contamination is present and you drop the purge rate too low, which risk rises most in the simulator?

Unanswered
Chapter 6 / Practice 4

Q29. In this teaching JavaScript implementation, what is thrown when an input violates a precondition?

Unanswered