Consider this differential algebraic model of a batch reactor [1]:
The above mathematical description can be transcribed into an MLDO model as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | # Variable/parameter declarations
params:
k10 = 0.535e11; k20 = 0.461e18;
E1 = 1.8e4; E2 = 3.0e4; R = 2;
diffvars:
x1; x2;
algvars:
k1; k2;
controlvars:
T;
# Optimization Problem
minimize:
-x2(tf);
dae:
$x1 = -k1*x1;
$x2 = k1*x1 - k2*x2;
k1 = k10*exp(-E1/(R*T));
k2 = k20*exp(-E2/(R*T));
init:
x1(0) = 0.53;
x2(0) = 0.43;
constraints:
T >= 273;
T <= 500;
# Solution settings
display:
x1; x2;
modelconfig:
nFE = 8;
nCOL = 2;
tf = 8;
|
The modelconfig section above specifies that the model is to be discretized using orthogonal collocation (the default method). The resulting simultaneous optimization problem will have 8 finite elements (nFE), 2 collocation points (nCOL), and will be integrated from 0 to a final time of 8 (tf). The display section tells MLDO to plot the trajectories for x1 and x2 in using a user-specified visualization module (e.g. Sparklines, Matlab, etc.).
- MLDO syntax (variable names, keywords, etc.) is case-sensitive.
- A model comprises sections. Each section name ends with a colon, :. Sections can be written in any order.
- Each section in turn contains one or more statements. A semicolon (;) marks the end of each statement.
- A comment starts with a hash (#) and goes till the end of the line.
- MLDO model filenames are given the extension .mldo.
- All variables and parameters must be declared in one of the following sections (params, diffvars, controlvars, algvars, designvars) before they can be used.
- Valid variable/parameter names begin with an alphabet, and may be followed by alphabets, numbers or an underscore (_). Names are not limited in length.
Section names Desription params constant parameters in the model diffvars differential variable declarations (all variables that exist as a derivative $ in this model) algvars algebraic variable declarations controlvars control input variable declarations (assumed to be piecewise-constant decision variables) designvars non-time-varying scalar variable declarations minimize objective function (minimize). To maximize, flip the sign of the function. minimizecustom custom section used to specify objective directly in the AMPL language. Takes precedence over minimize. dae equality constraints (typically a differential-algebraic-equation system) init initial values of differential variables constraints inequality constraints modelconfig model-specific configuration parameters display variables in the solution results to be displayed (passed on to the visualization module) addons add-on components for custom model formulation
Operators Description $x Time-derivative of x = \(\dot x\) x(0) Initial value of x = \(x(0)\) x(tf) Final value of x = \(x(t_f)\) x = y x is equal to y (equality and assignment are both denoted = in MLDO) x <= y x is less than or equal to y x >= y x is greater than or equal to y x != y (only in indexing sets) x not equal to y x mod y (only in indexing sets) x modulo y (the remainder obtained when x/y
Note
Strict inequality operators > and < are unsupported (but can be approximated up to a numerical tolerance using <= and >=.
In order to use array variables, we introduce the idea of indexing sets. Indexing sets are used to specify the indices in variables, parameters and constraints. They are written in set-builder notation:
1 | {ir1, ir2, ... irn: pred1, pred2, ... predn}
|
where ir are index ranges (e.g. i in 1..3), and pred are logical predicates (e.g. i != 2).
Declaring array variables/parameters
In declaration sections, one can write:
1 2 3 4 | algvars:
x{i in 1..3}; # x[i], for i=1, 2, 3
y{i in 1..3, j in 1..4}; # y[i,j], for i=1, 2, 3 and j=1, 2, 3, 4
z{i in 1..3: i != 2}; # z[i], for i=1, 3
|
Constraints with indices
Similarly, for constraints one can write:
1 2 3 4 5 | dae:
x[i] = y[i], {i in 1..3}; # x[i] = y[i], for i=1, 2, 3
y[i,j] = x[i], {i in 1..3, j in 1..4}; # y[i,j] = x[i], for i=1, 2, 3 and j=1, 2, 3, 4
constraints:
z{i in 1..3: i != 2} >= 0; # z[i] >= 0, for i=1, 3
|