Examples.PHNeutralizationPlant ​
pH neutralization in a continuously stirred tank reactor, from the ModelPredictiveControl.jl DAE tutorial ("Nonlinear Design (DAE)"): a weak acid (acetic acid, inflow q_Ain [L/min] of feed concentration c_Ain [mol/L]) is neutralized by a strong base (sodium hydroxide, inflow q_Bin of feed concentration c_Bin), and an overflow weir keeps the volume V [L] constant. The time unit is the hour, hence the factor 60 in the mass balances of the total acid species c_A and of the base c_B:
with
The acid feed concentration is dc_Ain_in carries the actual change of the feed and w is connected to zero; a controller and an estimator built from this component name both inputs in disturbance_inputs, so that d is a state variable they estimate and predict as a constant. The same component is the simulated plant, the prediction model of the controller and the model of the estimator in PHNeutralizationMPCExample.
Usage ​
MPCComponents.Examples.PHNeutralizationPlant(c_Bin=0.1, c_Ain0=0.1, Kw=1e-14, Ka=1.75e-5, V=1000.0, c_A0=0.025, c_B0=0.025)
Parameters: ​
| Name | Description | Units | Default value |
|---|---|---|---|
c_Bin | Feed concentration of the strong base [mol/L] | – | 0.1 |
c_Ain0 | Nominal feed concentration of the weak acid [mol/L] | – | 0.1 |
Kw | Water dissociation constant [mol²/L²] | – | 1e-14 |
Ka | Acid dissociation constant [mol/L] | – | 1.75e-5 |
V | Reactor volume [L] | – | 1000.0 |
c_A0 | Initial total concentration of the acid species [mol/L] | – | 0.025 |
c_B0 | Initial concentration of the base [mol/L] | – | 0.025 |
Connectors ​
q_Bin_in- This connector represents a real signal as an input to a component (RealInput)q_Ain_in- This connector represents a real signal as an input to a component (RealInput)dc_Ain_in- This connector represents a real signal as an input to a component (RealInput)w- This connector represents a real signal as an input to a component (RealInput)pH_out- This connector represents a real signal as an output from a component (RealOutput)
Variables ​
| Name | Description | Units |
|---|---|---|
c_A | Total concentration of the acid species (undissociated acid and acetate ion) [mol/L] | – |
c_B | Concentration of the base (sodium ion) [mol/L] | – |
d | State of the disturbance model of the acid feed concentration [mol/L] | – |
pH | pH of the solution | – |
c_Ain | Feed concentration of the weak acid [mol/L] | – |
q_out | Outflow [L/min] | – |
Behavior ​
Behavior of this component cannot be rendered because it includes path variables.
Source ​
"""
pH neutralization in a continuously stirred tank reactor, from the ModelPredictiveControl.jl DAE
tutorial ("Nonlinear Design (DAE)"): a weak acid (acetic acid, inflow `q_Ain` [L/min] of feed
concentration `c_Ain` [mol/L]) is neutralized by a strong base (sodium hydroxide, inflow `q_Bin` of
feed concentration `c_Bin`), and an overflow weir keeps the volume `V` [L] constant. The time unit is
the hour, hence the factor 60 in the mass balances of the total acid species `c_A` and of the base
`c_B`:
```math
\\begin{aligned}
\\dot c_A &= \\frac{60}{V} \\left(q_{Ain} c_{Ain} - q_{out} c_A\\right) \\\\
\\dot c_B &= \\frac{60}{V} \\left(q_{Bin} c_{Bin} - q_{out} c_B\\right) \\\\
0 &= a_H + c_B - \\frac{K_w}{a_H} - \\frac{K_a c_A}{K_a + a_H}
\\end{aligned}
```
with ``q_{out} = q_{Ain} + q_{Bin}``. The last relation is the instantaneous charge balance of the
solution, with the hydrogen-ion activity ``a_H = 10^{-\\mathrm{pH}}``. The pH is the algebraic
variable of the model, which is therefore kept as a semi-explicit index-1 DAE rather than reduced to
an ODE by solving the cubic equation for ``a_H``; choosing the pH rather than ``a_H`` as the
algebraic variable keeps it within roughly 1 to 14 instead of spanning 14 orders of magnitude.
The acid feed concentration is ``c_{Ain} = c_{Ain,0} + \\Delta c_{Ain} + d`` with an integrating
disturbance model ``\\dot d = w``. In simulation, the deviation `dc_Ain_in` carries the actual change
of the feed and `w` is connected to zero; a controller and an estimator built from this component name
both inputs in `disturbance_inputs`, so that `d` is a state variable they estimate and predict as a
constant. The same component is the simulated plant, the prediction model of the controller and the
model of the estimator in `PHNeutralizationMPCExample`.
"""
component PHNeutralizationPlant
"Inflow of the strong base [L/min]"
q_Bin_in = RealInput() {"Dyad": {"placement": {"diagram": {"x1": -100, "x2": 0, "y1": 50, "y2": 150}}}}
"Inflow of the weak acid [L/min]"
q_Ain_in = RealInput() {
"Dyad": {"placement": {"diagram": {"x1": -100, "x2": 0, "y1": 316, "y2": 416}}}
}
"Deviation of the feed concentration of the weak acid from its nominal value [mol/L]"
dc_Ain_in = RealInput() {
"Dyad": {"placement": {"diagram": {"x1": -100, "x2": 0, "y1": 583, "y2": 683}}}
}
"Input of the integrating disturbance model of the acid feed concentration [mol/(L h)]"
w = RealInput() {
"Dyad": {"placement": {"diagram": {"x1": -100, "x2": 0, "y1": 850, "y2": 950}}}
}
"pH of the solution"
pH_out = RealOutput() {
"Dyad": {"placement": {"diagram": {"x1": 1000, "x2": 1100, "y1": 450, "y2": 550}}}
}
"Feed concentration of the strong base [mol/L]"
parameter c_Bin::Real = 0.1
"Nominal feed concentration of the weak acid [mol/L]"
parameter c_Ain0::Real = 0.1
"Water dissociation constant [mol²/L²]"
parameter Kw::Real = 1e-14
"Acid dissociation constant [mol/L]"
parameter Ka::Real = 1.75e-5
"Reactor volume [L]"
parameter V::Real = 1000.0
"Initial total concentration of the acid species [mol/L]"
parameter c_A0::Real = 0.025
"Initial concentration of the base [mol/L]"
parameter c_B0::Real = 0.025
"Total concentration of the acid species (undissociated acid and acetate ion) [mol/L]"
variable c_A::Real(initial = c_A0)
"Concentration of the base (sodium ion) [mol/L]"
variable c_B::Real(initial = c_B0)
"State of the disturbance model of the acid feed concentration [mol/L]"
variable d::Real(initial = 0.0)
"pH of the solution"
variable pH::Real
"Feed concentration of the weak acid [mol/L]"
variable c_Ain::Real
"Outflow [L/min]"
variable q_out::Real
relations
guess pH = 7.0
der(d) = w
c_Ain = c_Ain0 + dc_Ain_in + d
q_out = q_Ain_in + q_Bin_in
der(c_A) = 60.0 / V * (q_Ain_in * c_Ain - q_out * c_A)
der(c_B) = 60.0 / V * (q_Bin_in * c_Bin - q_out * c_B)
# Charge balance with the hydrogen-ion activity a_H = 10^(-pH) written out, so that the pH is the
# only algebraic variable of the model
0 = 10.0 ^ (-pH) + c_B - Kw * 10.0 ^ pH - Ka * c_A / (Ka + 10.0 ^ (-pH))
pH_out = pH
metadata {"Dyad": {"doc": {"behavior": false}}}
endFlattened Source
"""
pH neutralization in a continuously stirred tank reactor, from the ModelPredictiveControl.jl DAE
tutorial ("Nonlinear Design (DAE)"): a weak acid (acetic acid, inflow `q_Ain` [L/min] of feed
concentration `c_Ain` [mol/L]) is neutralized by a strong base (sodium hydroxide, inflow `q_Bin` of
feed concentration `c_Bin`), and an overflow weir keeps the volume `V` [L] constant. The time unit is
the hour, hence the factor 60 in the mass balances of the total acid species `c_A` and of the base
`c_B`:
```math
\\begin{aligned}
\\dot c_A &= \\frac{60}{V} \\left(q_{Ain} c_{Ain} - q_{out} c_A\\right) \\\\
\\dot c_B &= \\frac{60}{V} \\left(q_{Bin} c_{Bin} - q_{out} c_B\\right) \\\\
0 &= a_H + c_B - \\frac{K_w}{a_H} - \\frac{K_a c_A}{K_a + a_H}
\\end{aligned}
```
with ``q_{out} = q_{Ain} + q_{Bin}``. The last relation is the instantaneous charge balance of the
solution, with the hydrogen-ion activity ``a_H = 10^{-\\mathrm{pH}}``. The pH is the algebraic
variable of the model, which is therefore kept as a semi-explicit index-1 DAE rather than reduced to
an ODE by solving the cubic equation for ``a_H``; choosing the pH rather than ``a_H`` as the
algebraic variable keeps it within roughly 1 to 14 instead of spanning 14 orders of magnitude.
The acid feed concentration is ``c_{Ain} = c_{Ain,0} + \\Delta c_{Ain} + d`` with an integrating
disturbance model ``\\dot d = w``. In simulation, the deviation `dc_Ain_in` carries the actual change
of the feed and `w` is connected to zero; a controller and an estimator built from this component name
both inputs in `disturbance_inputs`, so that `d` is a state variable they estimate and predict as a
constant. The same component is the simulated plant, the prediction model of the controller and the
model of the estimator in `PHNeutralizationMPCExample`.
"""
component PHNeutralizationPlant
"Inflow of the strong base [L/min]"
q_Bin_in = RealInput() {"Dyad": {"placement": {"diagram": {"x1": -100, "x2": 0, "y1": 50, "y2": 150}}}}
"Inflow of the weak acid [L/min]"
q_Ain_in = RealInput() {
"Dyad": {"placement": {"diagram": {"x1": -100, "x2": 0, "y1": 316, "y2": 416}}}
}
"Deviation of the feed concentration of the weak acid from its nominal value [mol/L]"
dc_Ain_in = RealInput() {
"Dyad": {"placement": {"diagram": {"x1": -100, "x2": 0, "y1": 583, "y2": 683}}}
}
"Input of the integrating disturbance model of the acid feed concentration [mol/(L h)]"
w = RealInput() {
"Dyad": {"placement": {"diagram": {"x1": -100, "x2": 0, "y1": 850, "y2": 950}}}
}
"pH of the solution"
pH_out = RealOutput() {
"Dyad": {"placement": {"diagram": {"x1": 1000, "x2": 1100, "y1": 450, "y2": 550}}}
}
"Feed concentration of the strong base [mol/L]"
parameter c_Bin::Real = 0.1
"Nominal feed concentration of the weak acid [mol/L]"
parameter c_Ain0::Real = 0.1
"Water dissociation constant [mol²/L²]"
parameter Kw::Real = 1e-14
"Acid dissociation constant [mol/L]"
parameter Ka::Real = 1.75e-5
"Reactor volume [L]"
parameter V::Real = 1000.0
"Initial total concentration of the acid species [mol/L]"
parameter c_A0::Real = 0.025
"Initial concentration of the base [mol/L]"
parameter c_B0::Real = 0.025
"Total concentration of the acid species (undissociated acid and acetate ion) [mol/L]"
variable c_A::Real(initial = c_A0)
"Concentration of the base (sodium ion) [mol/L]"
variable c_B::Real(initial = c_B0)
"State of the disturbance model of the acid feed concentration [mol/L]"
variable d::Real(initial = 0.0)
"pH of the solution"
variable pH::Real
"Feed concentration of the weak acid [mol/L]"
variable c_Ain::Real
"Outflow [L/min]"
variable q_out::Real
relations
guess pH = 7.0
der(d) = w
c_Ain = c_Ain0 + dc_Ain_in + d
q_out = q_Ain_in + q_Bin_in
der(c_A) = 60.0 / V * (q_Ain_in * c_Ain - q_out * c_A)
der(c_B) = 60.0 / V * (q_Bin_in * c_Bin - q_out * c_B)
# Charge balance with the hydrogen-ion activity a_H = 10^(-pH) written out, so that the pH is the
# only algebraic variable of the model
0 = 10.0 ^ (-pH) + c_B - Kw * 10.0 ^ pH - Ka * c_A / (Ka + 10.0 ^ (-pH))
pH_out = pH
metadata {"Dyad": {"doc": {"behavior": false}}}
endTest Cases ​
No test cases defined.
Related ​
Examples
Experiments
Analyses