Metabolism Simulation Programs

Interactive simulations exploring the quantitative and computational side of human metabolism. From enzyme kinetics and glycolytic flux to whole-body glucose homeostasis and cancer metabolism, these programs let you adjust parameters and observe how metabolic systems respond in real time.

1. Michaelis-Menten Enzyme Kinetics

The Michaelis-Menten equation is the cornerstone of enzyme kinetics, describing how reaction velocity depends on substrate concentration. For a simple enzyme-catalyzed reaction where enzyme E binds substrate S to form product P via an intermediate complex ES, the steady-state rate equation is:

$$v = \frac{V_{\max}[S]}{K_m + [S]}$$

Here \(V_{\max} = k_{\text{cat}}[E]_T\) is the maximum velocity when all enzyme is saturated, and \(K_m\) is the Michaelis constant, equal to the substrate concentration at which \(v = V_{\max}/2\). A low \(K_m\) indicates high substrate affinity. The Lineweaver-Burk double-reciprocal plot linearizes this relationship:

$$\frac{1}{v} = \frac{K_m}{V_{\max}} \cdot \frac{1}{[S]} + \frac{1}{V_{\max}}$$

This simulation plots both the hyperbolic Michaelis-Menten curve and its Lineweaver-Burk linearization, annotating the key kinetic parameters graphically. Adjust the parameters below to explore how enzyme affinity and catalytic capacity shape the velocity profile.

Python
Parameters

Maximum velocity

Michaelis constant

Maximum substrate concentration

script.py90 lines

Click Run to execute the Python code

Code will be executed with Python 3 on the server

Understanding the Results

The left plot shows the classic hyperbolic saturation curve. At low \([S] \ll K_m\), the rate increases approximately linearly with slope \(V_{\max}/K_m\) (catalytic efficiency). At high \([S] \gg K_m\), the enzyme is saturated and the rate plateaus at \(V_{\max}\). The yellow dot marks the half-saturation point.

The Lineweaver-Burk plot is the double-reciprocal linearization. The y-intercept gives \(1/V_{\max}\) and the x-intercept gives \(-1/K_m\). While useful historically for parameter estimation, this transform amplifies errors at low substrate concentrations.

2. Enzyme Inhibition Comparison

Enzyme inhibitors are central to pharmacology and metabolic regulation. The four main types of reversible inhibition each produce characteristic changes in the apparent kinetic parameters. Competitive inhibitors bind the active site, increasing the apparent \(K_m\) without affecting \(V_{\max}\):

$$v_{\text{competitive}} = \frac{V_{\max}[S]}{K_m\left(1 + \frac{[I]}{K_i}\right) + [S]}$$

Uncompetitive inhibitors bind only the ES complex, decreasing both apparent \(K_m\) and apparent \(V_{\max}\) by the same factor \(\alpha' = 1 + [I]/K_i'\). Mixed (noncompetitive when \(K_i = K_i'\)) inhibitors bind both E and ES, reducing\(V_{\max}\) while changing \(K_m\) depending on relative binding affinities.

$$v_{\text{mixed}} = \frac{V_{\max}[S]}{\alpha K_m + \alpha' [S]}, \quad \alpha = 1+\frac{[I]}{K_i}, \quad \alpha' = 1+\frac{[I]}{K_i'}$$
Python
Parameters

Maximum velocity

Michaelis constant

Inhibition constant

Inhibitor concentration

script.py96 lines

Click Run to execute the Python code

Code will be executed with Python 3 on the server

Understanding the Results

On the Lineweaver-Burk plot, each inhibition type has a distinct signature: competitive inhibitors change the slope (x-intercept shifts) but share the same y-intercept; uncompetitive inhibitors produce parallel lines (same slope, different intercepts); and mixed/noncompetitive inhibitors change both slope and y-intercept.

Try increasing \([I]\) to see how the curves diverge. At very high substrate concentrations, competitive inhibition can be overcome (curves converge), but uncompetitive and mixed inhibition cannot.

3. Glycolysis Flux Model

Glycolysis converts one molecule of glucose into two molecules of pyruvate through a 10-step enzymatic pathway. The net reaction is:

$$\text{Glucose} + 2\text{NAD}^+ + 2\text{ADP} + 2\text{P}_i \rightarrow 2\text{Pyruvate} + 2\text{NADH} + 2\text{ATP} + 2\text{H}_2\text{O}$$

This simulation models the flux through the three key irreversible regulatory steps: hexokinase (HK), phosphofructokinase-1 (PFK-1), and pyruvate kinase (PK). Each enzyme follows Michaelis-Menten kinetics, and the intermediates glucose-6-phosphate (G6P), fructose-6-phosphate (F6P), fructose-1,6-bisphosphate (FBP), and pyruvate are tracked as a simplified ODE system. PFK-1 is the principal committed step and rate-limiting enzyme, allosterically activated by AMP and inhibited by ATP and citrate.

Python
Parameters

Starting glucose concentration

PFK-1 activity factor (1 = normal)

Hexokinase Vmax factor

script.py79 lines

Click Run to execute the Python code

Code will be executed with Python 3 on the server

Understanding the Results

Glucose is consumed by hexokinase and converted through intermediates to pyruvate. Because PFK-1 is the slowest step, you can see F6P accumulates while the PFK activity factor is low. Increasing PFK activity relieves this bottleneck and accelerates the entire pathway.

Note that each glucose yields two pyruvates (the C6 sugar is cleaved into two C3 fragments at the aldolase step). Try lowering PFK activity to 0.2 to simulate citrate inhibition, or raising HK Vmax to simulate insulin-stimulated glucose uptake.

4. TCA Cycle Dynamics

The tricarboxylic acid (TCA) cycle, also known as the citric acid cycle or Krebs cycle, is the central metabolic hub where acetyl-CoA is oxidized to \(\text{CO}_2\), generating the reduced cofactors NADH and \(\text{FADH}_2\) that drive oxidative phosphorylation. Each turn of the cycle produces:

$$\text{Acetyl-CoA} + 3\text{NAD}^+ + \text{FAD} + \text{GDP} + \text{P}_i \rightarrow 2\text{CO}_2 + 3\text{NADH} + \text{FADH}_2 + \text{GTP} + \text{CoA}$$

This simulation models the concentrations of key TCA intermediates over time as acetyl-CoA enters the cycle. The rate of each step depends on substrate availability and the \(\text{NAD}^+/\text{NADH}\) ratio, which controls the oxidative steps catalyzed by isocitrate dehydrogenase, alpha-ketoglutarate dehydrogenase, and malate dehydrogenase.

Python
Parameters

Rate of acetyl-CoA entering the cycle

Oxidized/reduced cofactor ratio

script.py84 lines

Click Run to execute the Python code

Code will be executed with Python 3 on the server

Understanding the Results

The cycle reaches a quasi-steady state where intermediate concentrations stabilize. With a high \(\text{NAD}^+/\text{NADH}\) ratio, the three NAD-dependent dehydrogenases are accelerated, draining isocitrate, alpha-KG, and malate faster. Lowering this ratio (simulating reduced oxygen supply) causes these intermediates to accumulate.

OAA concentration is critical because it must combine with acetyl-CoA in the citrate synthase step. If OAA is depleted (anaplerotic reactions are insufficient), the cycle stalls regardless of acetyl-CoA availability.

5. Electron Transport Chain & ATP Yield Calculator

The electron transport chain (ETC) couples the oxidation of NADH and \(\text{FADH}_2\) to the generation of a proton gradient across the inner mitochondrial membrane. The free energy released by electron transfer through Complexes I, III, and IV is:

$$\Delta G = -nF\Delta E'_0, \quad \text{where } \Delta E'_0(\text{NADH} \to \text{O}_2) = 1.14\text{ V}$$

The P/O ratio defines how many ATP are produced per oxygen atom reduced. For NADH (entering at Complex I), the theoretical P/O ratio is approximately 2.5; for \(\text{FADH}_2\) (entering at Complex II), it is approximately 1.5. This Fortran program calculates total ATP yield and thermodynamic efficiency based on the standard free energy of glucose oxidation (\(\Delta G^\circ = -2870\) kJ/mol) and ATP hydrolysis (\(\Delta G^\circ = -30.5\) kJ/mol).

Fortran
Parameters

Number of NADH molecules

Number of FADH2 molecules

ATP per 1/2 O2 from NADH

ATP per 1/2 O2 from FADH2

Substrate-level phosphorylation ATP

program.f9053 lines

Click Run to execute the Fortran code

Code will be compiled with gfortran and executed on the server

Understanding the Results

For complete glucose oxidation (glycolysis + pyruvate dehydrogenase + TCA cycle), the default values yield 10 NADH, 2 \(\text{FADH}_2\), and 4 substrate-level ATP (including 2 GTP from succinyl-CoA synthetase). With standard P/O ratios of 2.5 and 1.5, this gives approximately 30-32 ATP per glucose.

The thermodynamic efficiency of about 34% reflects the fraction of glucose free energy captured as ATP. The remainder is released as heat, which is essential for maintaining body temperature. Try comparing glucose vs palmitate by adjusting to 31 NADH, 15 \(\text{FADH}_2\), and 1 substrate-level ATP.

6. Beta-Oxidation Energy Calculator

Beta-oxidation is the catabolic process by which fatty acyl-CoA is sequentially shortened by two carbons per cycle, producing acetyl-CoA, NADH, and \(\text{FADH}_2\) at each step. For a saturated fatty acid with \(n\) carbon atoms, the number of beta-oxidation cycles is \(n/2 - 1\), yielding:

$$\text{Acetyl-CoA} = \frac{n}{2}, \quad \text{NADH} = \frac{n}{2}-1, \quad \text{FADH}_2 = \frac{n}{2}-1$$

Each acetyl-CoA entering the TCA cycle yields 3 NADH + 1 \(\text{FADH}_2\) + 1 GTP, so the total ATP yield from a single fatty acid molecule is substantial. However, activation to fatty acyl-CoA costs 2 ATP equivalents. This program calculates the complete energy balance and displays a breakdown by source.

Python
Parameters

Even-numbered carbon chain length

script.py114 lines

Click Run to execute the Python code

Code will be executed with Python 3 on the server

Understanding the Results

Palmitate (C16) yields approximately 106 net ATP, far exceeding the ~30 ATP from glucose. This is why fats are the most energy-dense macronutrient (9 kcal/g vs 4 kcal/g for carbohydrates). The right panel shows that ATP per carbon increases with chain length because the fixed 2 ATP activation cost becomes proportionally smaller.

The majority of ATP comes from the TCA cycle NADH, reflecting the fact that complete oxidation of acetyl-CoA through the cycle and ETC is the dominant energy source.

7. Urea Cycle & Nitrogen Balance

The urea cycle is the primary pathway for disposing of excess nitrogen from amino acid catabolism. It converts toxic ammonia (\(\text{NH}_3\)) and the amino group of aspartate into urea, which is excreted by the kidneys. The net reaction is:

$$\text{NH}_3 + \text{CO}_2 + \text{Aspartate} + 3\text{ATP} \rightarrow \text{Urea} + \text{Fumarate} + 2\text{ADP} + \text{AMP} + 2\text{P}_i + \text{PP}_i$$

This Fortran program calculates nitrogen balance based on dietary protein intake. Since proteins average about 16% nitrogen by mass, and each gram of nitrogen produces approximately\(2.14\) g of urea (MW urea = 60, MW N = 14, ratio = 60/28), we can estimate daily urea production and the ATP cost of nitrogen disposal.

Fortran
Parameters

Daily dietary protein

Fraction of amino acids oxidized (vs used for synthesis)

program.f9071 lines

Click Run to execute the Fortran code

Code will be compiled with gfortran and executed on the server

Understanding the Results

On a typical 80 g/day protein diet with 70% oxidation, the body must dispose of about 9 g of nitrogen daily as urea. This costs approximately 4 ATP per urea molecule, representing a non-trivial metabolic expense of nitrogen disposal.

In urea cycle disorders (e.g., ornithine transcarbamylase deficiency), ammonia accumulates to toxic levels, causing encephalopathy. Treatment involves reducing protein intake and providing alternative nitrogen disposal pathways (sodium benzoate, phenylbutyrate). Try increasing protein intake to see how the nitrogen load scales.

8. Blood Glucose Homeostasis

Blood glucose is maintained within a narrow range (4-6 mM fasting) by the opposing actions of insulin and glucagon. After a meal, rising glucose stimulates pancreatic beta-cells to secrete insulin, which promotes glucose uptake into muscle and adipose tissue and stimulates glycogen synthesis. Between meals, falling glucose triggers alpha-cell glucagon secretion, which activates hepatic glycogenolysis and gluconeogenesis.

This model uses a system of ODEs to simulate the glucose-insulin-glucagon dynamics following a glucose load. In type 2 diabetes, insulin resistance reduces the effectiveness of insulin, requiring higher insulin levels to achieve the same glucose disposal. The model captures this by scaling the insulin sensitivity parameter \(\sigma\):

$$\frac{d[\text{Glucose}]}{dt} = R_{\text{meal}}(t) + R_{\text{glucagon}} - \sigma \cdot [\text{Insulin}] \cdot [\text{Glucose}] - k_{\text{basal}} \cdot [\text{Glucose}]$$
Python
Parameters

Oral glucose load (75g = standard OGTT)

1.0 = normal, <1 = resistant

Relative basal glucagon level

script.py94 lines

Click Run to execute the Python code

Code will be executed with Python 3 on the server

Understanding the Results

In the normal response (solid lines), glucose rises after the meal, peaks around 30-60 minutes, then returns to baseline within 2 hours as insulin-mediated uptake clears it. Insulin mirrors the glucose curve with a slight delay, while glucagon is suppressed during the postprandial period.

In the type 2 diabetes simulation (dashed lines, 30% of normal sensitivity), glucose rises higher and takes much longer to return to baseline. The beta-cells compensate by secreting more insulin (hyperinsulinemia), but the reduced tissue response means glucose disposal is impaired. This is the hallmark of insulin resistance seen in the early stages of type 2 diabetes.

9. Metabolic Flux Analysis

Metabolic flux analysis (MFA) determines the rates of metabolic reactions in a network at steady state. At any metabolic branch point, the flux must be conserved (Kirchhoff-like law). For glucose entering a cell, the three major fates are glycolysis (energy production), the pentose phosphate pathway (PPP, for NADPH and ribose-5-phosphate), and glycogenesis (storage). The fluxes must satisfy:

$$J_{\text{uptake}} = J_{\text{glycolysis}} + J_{\text{PPP}} + J_{\text{glycogenesis}}$$

This simulation solves a simple linear program to find the optimal flux distribution given constraints on ATP demand and NADPH demand. Glycolysis yields 2 ATP per glucose; the PPP yields 2 NADPH per glucose-6-phosphate entering the oxidative branch; glycogenesis consumes 1 ATP per glucose stored. The solver maximizes glucose storage while meeting energy and biosynthetic demands.

Python
Parameters

Total glucose uptake rate

Cellular ATP requirement

NADPH requirement (biosynthesis)

script.py124 lines

Click Run to execute the Python code

Code will be executed with Python 3 on the server

Understanding the Results

The pie chart shows how glucose is partitioned among the three pathways. The solver first allocates enough flux to the PPP to meet NADPH demand, then distributes the remainder between glycolysis and glycogenesis to meet ATP demand while maximizing storage.

The right panel shows how the flux distribution shifts as ATP demand increases: glycolysis claims a larger share at the expense of glycogenesis. When ATP demand exceeds the capacity of available glucose, glycogen storage drops to zero and all glucose flows through glycolysis. This mirrors the fed-to-fasting transition in vivo.

10. The Warburg Effect

Otto Warburg observed in 1924 that cancer cells preferentially use glycolysis for ATP production even in the presence of oxygen — a phenomenon called aerobic glycolysis or the Warburg effect. While oxidative phosphorylation yields ~36 ATP per glucose, aerobic glycolysis yields only 2 ATP but proceeds much faster and provides biosynthetic precursors.

The tradeoff can be understood quantitatively. If the glycolytic rate is \(r_{\text{glyc}}\) (glucose/s) and oxidative phosphorylation rate is \(r_{\text{oxphos}}\), then the total ATP production rate for a cell using fraction \(f\) of glucose glycolytically is:

$$R_{\text{ATP}} = 2 \cdot f \cdot J_{\text{glc}} + 36 \cdot (1 - f) \cdot J_{\text{glc}} \cdot \frac{[\text{O}_2]}{K_{\text{O}_2} + [\text{O}_2]}$$

This simulation compares the metabolic strategies, showing that while glycolysis is less efficient per glucose, it can produce ATP faster when glucose is abundant. Cancer cells exploit this by upregulating glucose transporters (GLUT1) and glycolytic enzymes.

Python
Parameters

Glucose uptake rate

Relative oxygen availability (1 = normoxia)

Fraction of glucose going to glycolysis

script.py142 lines

Click Run to execute the Python code

Code will be executed with Python 3 on the server

Understanding the Results

The top-left panel reveals the key insight: as the glycolytic fraction increases, total ATP production rate decreases because glycolysis is 18 times less efficient per glucose than oxidative phosphorylation. However, the bottom-right panel shows the resolution of the Warburg paradox: cancer cells compensate by massively upregulating glucose uptake (via GLUT1), so despite low efficiency, their absolute ATP production rate can exceed that of normal cells.

The high lactate production (top-right) is a clinical hallmark exploited in FDG-PET imaging, where the glucose analog fluorodeoxyglucose accumulates preferentially in tumors with high glycolytic rates. Try reducing O2 availability to see how hypoxia forces even normal cells toward glycolysis, mimicking the core of the tumor microenvironment.