Skip to content
LIBRARY
Examples.PHNeutralizationPlant.md

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:

Misplaced &

with   . The last relation is the instantaneous charge balance of the solution, with the hydrogen-ion activity  . 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 ; choosing the pH rather than as the algebraic variable keeps it within roughly 1 to 14 instead of spanning 14 orders of magnitude.

The acid feed concentration is       with an integrating disturbance model    . 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.

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: ​

NameDescriptionUnitsDefault value
c_BinFeed concentration of the strong base [mol/L]–0.1
c_Ain0Nominal feed concentration of the weak acid [mol/L]–0.1
KwWater dissociation constant [mol²/L²]–1e-14
KaAcid dissociation constant [mol/L]–1.75e-5
VReactor volume [L]–1000.0
c_A0Initial total concentration of the acid species [mol/L]–0.025
c_B0Initial 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 ​

NameDescriptionUnits
c_ATotal concentration of the acid species (undissociated acid and acetate ion) [mol/L]–
c_BConcentration of the base (sodium ion) [mol/L]–
dState of the disturbance model of the acid feed concentration [mol/L]–
pHpH of the solution–
c_AinFeed concentration of the weak acid [mol/L]–
q_outOutflow [L/min]–

Behavior ​

Behavior of this component cannot be rendered because it includes path variables.

Source ​

dyad
"""
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}}}
end
Flattened Source
dyad
"""
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}}}
end


Test Cases ​

No test cases defined.

  • Examples

  • Experiments

  • Analyses