SETS: ! (unitcom5);
! Electrical generator unit commitment planning;
! Keywords: Electricity generation, Hydro electric,
Multi-period planning, Unit commitment;
! The set of all generators;
GENR: CF, CG, CS, MXG, INITY;
PERIOD: DEM;
GXP( GENR, PERIOD): X, YON, YOF, Z;
! Units with time varying capacity;
VGEN( GENR);
VXP( VGEN, PERIOD): VMXG;
! Hydro and pumped storage units;
HNP( GENR): FLO, IMX, INI;
HXP( HNP, PERIOD): INV, SPILL;
! Pumped storage units;
STORE( GENR): PF, PMX;
SXP( STORE, PERIOD): W;
ENDSETS DATA:
GENR = COAL01 GAS001 GAS002 WIND01 HYDRO1 PUMP01;! The units;
CF = 2775 5980 5290 1 2.0 1.9;! Fixed cost/period if spinning;
CG = 14 22 25 1 1.1 2;! Cost/MWH generated;
CS = 90000 12900 8000 1700 800 790;! Cost to start spinning;
MXG = 1100 760 680 600 900 660;! Max gen capacity in period;
INITY = 0 0 0 0 0 0;! Initially spinning or not;
PERIOD = 1..24;
DEM = 900 1790 2380 2490 1520 1298 2200 1030
1900 2360 1900 1790 1690 1650 1600 1600
1700 1800 1900 1600 1400 1200 1100 1000; ! Demand in MWH;
! Units with variable capacity;
VGEN = WIND01; ! Capacity in each period;
VMXG = 180 210 270 280 310 200 300 250
150 100 100 100 100 90 90 100
120 120 130 130 130 140 150 170;
! Hydro and pumped storage units;
HNP = HYDRO1 PUMP01;! Name of the hydro and pumped units;
FLO = 220 0; ! Inflow per period;
IMX = 1000 970; ! Max inventory level;
INI = 200 0; ! Initial inventory;
! Pumped storage;
STORE = PUMP01;
PF = 1.3; ! MWH needed to put 1 MWH in storage;
PMX = 320; ! Max pumped into storage/period;
! Here the data are stored directly in the model file. Alternatively,
attribute DEM can be read from a spreadsheet by the statement:
DEM = @OLE( );
! if:
a) there is only one spreadsheet open in Excel,
b) there is a range in the spreadsheet of the appropriate
shape with name DEM;
! Similarly, answers can be sent back to the spreadsheet with
statements like:
@OLE( ) = X;
ENDDATA
SUBMODEL UnitCom:
! X(i,t) = amount generated by i in period t;
! Z(i,t) = 1 if i is running in t;
! YON(i,t) = 1 if i is started in t;
! YOF(i,t) = 1 if i is turned off in t;
! W(i,t) = amount pumped into i in period t;
! Minimize sum of start-up, spinning, and energy costs;
MIN = @SUM( GXP( I, T): CS(I)*YON(I,T) + CF(I)* Z(I,T) + CG(I)*X(I,T));
! Constraints applicable to all generators;
! Must satisfy demand + used for pumping;
@FOR( PERIOD( T):
@SUM( GENR( I): X(I,T)) = DEM(T) + @SUM(STORE(I): PF(I)*W(I,T)) ;
);
@FOR( GENR( I):
! Generator I has to be spinning (Z(I,T) =1) to get any power;
@FOR( PERIOD( T):
X(I,T) <= MXG( I) * Z(I,T);
);
@FOR( PERIOD( T):
@BIN(Z(I,T));
);
! Turn on YON(I,T) if generator I starts at the beginning of period T,
and YOF(I,T) if generator stops at the beginning of period T;
YON(I,1) - YOF(I,1) = Z(I,1) - INITY( I); ! Period 1 is special;
@FOR( PERIOD(T) | T #GT# 1:
YON(I,T) - YOF(I,T) = Z(I,T) - Z(I,T-1);
YON(I,T) + YOF(I,T) <= 1; ! Cannot both turn on and off in a period;
);
);
! These constraints apply to variable capacity units;
@FOR( VXP( I,T):
X(I,T) <= VMXG(I,T);
);
! For plain hydro, we have the inventory equations;
@FOR( HNP(I)| #NOT# @IN(STORE, I ):
! For period 1;
INI( I) + FLO(I) = INV(I,1) + X(I,1) + SPILL(I,1);
INV(I,1) <= IMX(I);
! Remaining periods;
@FOR( PERIOD(T)| T #GT# 1:
INV(I,T-1) + FLO(I) = INV(I,T) + X(I,T) + SPILL(I,T);
INV(I,T) <= IMX(I);
);
);
! For pumped storage;
@FOR( STORE(I):
! Beginning Inv + flow in + pumped in
= ending inv + generated + spilled;
! For period 1;
INI( I) + FLO(I) + W(I,1) = INV(I,1) + X(I,1) + SPILL(I,1);
INV(I,1) <= IMX(I);
W(I,1) <= PMX(I);
! Remaining periods;
@FOR( PERIOD(T)| T #GT# 1:
INV(I,T-1) + FLO(I)+ W(I,T) = INV(I,T) + X(I,T) + SPILL(I,T);
INV(I,T) <= IMX(I);
W(I,T) <= PMX( I)
);
);
ENDSUBMODEL
CALC:
@SET( 'TERSEO', 2); ! Set output level to TERSE;
@SOLVE(UnitCom);
@WRITE(@NEWLINE(1), ' Here is a simple report:', @NEWLINE(1));
@WRITE('Prd Demand ');
! List the names of the generators at the top;
@FOR( GENR(i):
@WRITE(' ',GENR(i));
);
@WRITE(@NEWLINE(1));
! Loop over the periods;
@FOR( PERIOD(t):
@WRITE(@FORMAT(t,'2.0f'),' ',@FORMAT(DEM(t),'6.1f'),' ');
@FOR( GENR(i):
@IFC(X(i,t) #GT# 0.001:
@WRITE(' ',@FORMAT(X(i,t),'7.2f'));
@ELSE
@WRITE(' '); ! Show blank if zero;
);
);
@WRITE(@NEWLINE(1));
);
ENDCALC
|