tanksize.gms : Tank Size Design Problem

**Description**

We discuss a tank design problem for a multi product plant, in which the optimal cycle time and the optimal campaign size are unknown. A mixed in- teger nonlinear programming formulation is presented, where non-convexities are due to the tank investment cost, storage cost, campaign setup cost and variable production rates. The objective of the optimization model is to minimize the sum of the production cost per ton per product produced. A continuous-time mathematical programming formulation for the problem is implemented with a fixed number of event points.

**Reference**

- Rebennack, S, Kallrath, J, and Pardalos, P M, Optimal Storage Design for a Multi-Product Plant: A Non-Convex MINLP Formulation. Computers and Chemical Engineering 35, 2 (2011), 255-271.

**Small Model of Type :** MINLP

**Category :** GAMS Model library

**Main file :** tanksize.gms

```
$Title Tank Size Design Problem - (TANKSIZE,SEQ=350)
$Ontext
We discuss a tank design problem for a multi product plant, in which the
optimal cycle time and the optimal campaign size are unknown. A mixed in-
teger nonlinear programming formulation is presented, where non-convexities
are due to the tank investment cost, storage cost, campaign setup cost and
variable production rates. The objective of the optimization model is to
minimize the sum of the production cost per ton per product produced. A
continuous-time mathematical programming formulation for the problem is
implemented with a fixed number of event points.
Rebennack, S, Kallrath, J, and Pardalos, P M, Optimal Storage Design
for a Multi-Product Plant: A Non-Convex MINLP Formulation. Tech. rep.,
University of Florida, 2009. Submitted to Computers and Chemical
Engineering
$Offtext
$eolcom //
$stitle Define the model size and data
Sets
p products / P1*P3 /
n event points / N1*N3 /;
Parameters
PRMIN(p) volume flow of products in m^3 per day
PRMAX(p) volume flow of products in m^3 per day
SLB(p) lower bound on inventory in m^3
SUB(p) upper bound on inventory in m^3
SI(p) initial inventory in m^3 (10% of the lower bound)
DLB(p) lower bound on PRODUCTION length d(n)
DUB(p) upper bound on PRODUCTION length d(n)
DEMAND(p) volume flow of products in m^3 per year!!
TS(p) campaign setup times in days
CSTI(p) tank variable cost per ton
CSTC(p) campaign setup cost
B variable part of the tank investment cost / 0.3271 /;
Table pdata(p,*)
prmin prmax slb sub si dlb dub demand ts csti cstc
P1 15.0 50.0 643.0 4018.36 707.0 1 40 4190 0.4 18.8304 10
P2 15.0 50.0 536.0 3348.63 589.0 1 40 3492 0.2 19.2934 20
P3 7.0 50.0 214.0 1339.45 235.0 1 40 1397 0.1 19.7563 30
;
$onechoV > assignpar.gms
$label start
%1(p) = pdata(p,'%1');
$shift
$if not x%1 == x $goto start
$offecho
$batinclude assignpar prmin prmax slb sub si dlb dub demand ts csti cstc
* Derived data
Parameters
DPD(p) compute the demand per day per product [tons per day]
L compute the demand per day [tons per day]
CAL longest campain
PRL maximum production length
CSTCMin minimum setup cost
CSTCMax maximum setup cost;
DPD(p) = DEMAND(p) / 365;
L = sum(p, DPD(p));
CSTI(p) = CSTI(p) / 365 ; // scale the storage cost
CAL = max(0, smax(p, DUB(p) + TS(p)));
PRL = max(0, smax(p, DUB(p)));
CSTCMin = smin(p, CSTC(p));
CSTCMax = smax(p, CSTC(p));
$stitle Model formulation
Alias(p,pp);
Positive variables
d(n) duration of the campaigns
pC(p,n) amount of product p produced in campaign n
s(p,n) amount of product p stored at the beginning of campaign n
sM(p) size of the product tanks in tons
sH(p,n) auxiliary variables
cI investment costs
cC campaign setup costs
cS variable storage costs
T cycle time;
Binary Variables
omega(p,n) binary variable indicating product in campaign;
Variables
cPT cost per ton: the objective variable to minimize;
Equations
TIMECAP time capacity
UNIQUE(n) at most one product per campaign
MATBAL(p,n) material balance constraint
TANKCAP(p,n) tank capacity constraint
PPN1(p,n) compute the nonlinear products pR(rp)*d(n)*omega
PPN2(p,n) compute the nonlinear products pR(rp)*d(n)*omega
SCCam1(n) semi-continuous bound on campaigns
SCCam2(n) semi-continuous bound on campaigns
DEFcC campaign setup costs
DEFcI investment cost
DEFcS variable storage costs
DefsH(p,n) define the auxiliary variables
DEFcPT total costs per ton produced
NONIDLE(n) force not to be idle;
* time balance constraint with unknown cycle time T
TIMECAP.. sum(n, d(n) + sum (p, TS(p)*omega(p,n))) =e= T;
* at most one product per campaign
UNIQUE(n).. sum(p, omega(p,n)) =l= 1;
* no idle states are allowed
NONIDLE(n).. sum(p, DUB(p)*omega(p,n)) =g= d(n);
* material balance equation (steady state):
* storage at end of n for product p = storage at start of n+1 for product p
* storage at end of n for product p = storage at start of n
* + total production of product p in n
* - total demand in period n
MATBAL(p,n)..
s(p,n++1) =e= s(p,n) + pC(p,n) - DPD(p)*(d(n) + sum (pp, TS(pp)*omega(pp,n)));
* tank capacity constraint:
* this connects the tank desing capacity variable with the storage level
TANKCAP(p,n).. s(p,n) =l= sM(p);
* compute the nonlinear products: pR(p,n)*d(n)*omega
* connects the production of product p in period n with
* -> the omega variables
* -> the lenght of the PRODUCTION period
* -> the production rate
* PPN(p,n).. pC(p,nbl(n)) =e= pR(p,n)*d(n)*omega(p,n);
PPN1(p,n).. pC(p,n) =l= PRMAX(p)*d(n)*omega(p,n);
PPN2(p,n).. pC(p,n) =g= PRMIN(p)*d(n)*omega(p,n);
* semi-continuous lower and upper bound on campaigns
SCCam2(n).. d(n) =g= sum(p, DLB(p)*omega(p,n));
SCCam1(n).. d(n) =l= sum(p, DUB(p)*omega(p,n));
* define the total costs per ton: cPT
DEFcPT.. (cPT*L - cI )*T =e= cC + cS;
* define the campaign setup costs
DEFcC.. cC =e= sum((p,n), CSTC(p)*omega(p,n));
* define the tank investment costs
DEFcI.. cI =e= B*sum(p, sqrt(sM(p)));
* define the variable tank costs
DEFcS.. cS =e= sum((p,n), CSTI(p)*sH(p,n)
*(d(n) + sum(pp, TS(pp)*omega(pp,n))));
* auxiliary variables for the objective
DefsH(p,n).. sH(p,n) =e= 0.5*(s(p,n++1) + s(p,n)) - SLB(p);
* additional constraints to break symmetry
Equations
SEQUENCE(p,n) redundant consteraint on the omega
SYMMETRY(n) break the symmetry of active campaigns;
* if a product is produced during period n, then it cannot be produced during
* period n+1
SEQUENCE(p,n).. 1 - omega(p,n) =g= omega(p,n+1);
* break symmetry buy shift empty periods to the end
SYMMETRY(n).. sum(p, omega(p,n)) =g= sum(p, omega(p,n+1));
Model Sequenz /all/;
* lower und upper bound on inventory
s.lo(p,n) = SLB(p);
s.up(p,n) = SUB(p);
* initial storage
s.fx('P1','N1') = SLB('P1') ;
* the inital storage has some implications
omega.fx(p,'N1') = 0;
omega.fx('P1','N1') = 1;
omega.fx('P1','N2') = 0;
* lower and upper bound on tank size
sM.lo(p) = SLB(p);
sM.up(p) = SUB(p);
* Get out of the poor starting point
omega.l(p,n) = uniform(0,1);
Solve Sequenz using minlp minimizing cPT;
```