Dynamic matrix control tuning for a distillation column
DMC on a column is tuned with four numbers: a prediction horizon long enough to cover the slowest tray-to-tray response, a shorter control horizon, a move weight that trades speed against valve wear, and per-CV weights that decide which spec gives way when they conflict. Defaults are horizon 20, control horizon 5, move weight 0.1.
Dynamic matrix control predicts where the column is heading over a horizon, then picks the sequence of moves that minimises predicted error plus a penalty on the moves themselves. On a column that matters more than on most units, because reflux and reboil both move both product compositions — the loops interact, and single-loop PID fights itself.
Show the governing equations
The four numbers
| Knob | Default | Raise it to | Cost of raising it |
|---|---|---|---|
| Prediction horizon P | 20 | See the full response of the slowest CV | More computation; sluggish if far past settling |
| Control horizon M | 5 | Give the controller freedom on a hard move | More aggressive, less robust to model error |
| Move weight lambda | 0.1 | Calm a valve that is working too hard | Slower rejection of disturbances |
| CV weights W_y | equal | Protect the spec that must not move | The other CV gives way instead |
Rule of thumb for a column: set P to cover the slowest tray-to-tray response end to end, M to roughly a quarter of P, and then tune only lambda. Most bad column DMC is a move weight problem, not a horizon problem — the controller is either chattering the reflux valve or too damped to catch a feed disturbance, and both are lambda.
The overhead composition is usually the CV to weight highest: it is the spec that gets sold, and bottoms purity has the reboiler to absorb the correction.
Getting the model
DMC needs a step-response model. MaximaLabs identifies one from plant data rather than from a step-test campaign: a PRBS dither on the MVs, then a fit against the recorded CV response, so the loop can be commissioned without taking the column off spec for a week. The identified model lands as pending_model for review before it goes live — a model is never swapped underneath a running controller.