Home > matpower7.0 > most > lib > loadmd.m

loadmd

PURPOSE ^

LOADMD Loads all required data and constructs MD for MOST.

SYNOPSIS ^

function md = loadmd(mpci, transmati, xgdi, storagei, contabi, profilesi, trajdatai)

DESCRIPTION ^

LOADMD   Loads all required data and constructs MD for MOST.

   MD = LOADMD(MPC)
   MD = LOADMD(MPC, TRANSMAT)
   MD = LOADMD(MPC, TRANSMAT, XGD)
   MD = LOADMD(MPC, TRANSMAT, XGD, SD)
   MD = LOADMD(MPC, TRANSMAT, XGD, SD, CONTAB)
   MD = LOADMD(MPC, TRANSMAT, XGD, SD, CONTAB, PROFILES)
   MD = LOADMD(MPC, TRANSMAT, XGD, SD, CONTAB, PROFILES, TRAJDATA)
   MD = LOADMD(MPC, NT, ...)

   All inputs can have the format described below or can be given as
   strings containing the name of the MAT-file or M-file that contains the
   data in the proper format.

   Inputs:
       MPC:       a standard MATPOWER case struct, optionally with
                  additional fields such as 'genfuel' and 'i<type>'
                  NOTE: Bus numbers must be consecutive beginning at 1
                        (i.e. internal ordering).
       TRANSMAT:  (optional) NT dimensional cell array of matrices, where
                  TRANSMAT{t} is an NJ(t) x NJ(t-1) matrix containing the
                  transition probabilities from period t-1 to period t. The
                  first element TRANSMAT{1} is a column vector of transition
                  probabilities from period 0 (NJ(0) = 1) to period 1. For
                  deterministic cases, TRANSMAT can be specified simply as
                  an integer NT (number of periods), which gets expanded
                  internally to a cell array of 1's. Default value is 1.
       XGD:       (optional) xGenData struct, see LOADXGENDATA for details.
       SD:        (optional) StorageData struct, see LOADSTORAGEDATA for
                  details.
       CONTAB:    (optional) contingency table with master set of
                  contingencies used for security throughout entire horizon
       PROFILES:  (optional) a struct array of Profiles (see IDX_PROFILE
                  and APPLY_PROFLE for details), specifying changes in the
                  system and operational conditions, xGenData, StorageData
                  and/or contingencies across time periods and scenarios.
                  Alternatively, for backward compatibility with the
                  older centroids format, PROFILES can take the form of
                  a struct with the following fields:
                     .wind:  3-dim array (NT x NJ_MAX x num wind sites)
                     .load:  3-dim array (NT x NJ_MAX x num load zones)
                  If empty, no changes are made across time.
       TRAJDATA:  (optional) struct array in same format as PROFILES
                  specifying a set of trajectories for a stage 2 solution.
                  The J dimension of the profile in this case indexes the
                  trajectories.

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function md = loadmd(mpci, transmati, xgdi, storagei, contabi, profilesi, trajdatai)
0002 %LOADMD   Loads all required data and constructs MD for MOST.
0003 %
0004 %   MD = LOADMD(MPC)
0005 %   MD = LOADMD(MPC, TRANSMAT)
0006 %   MD = LOADMD(MPC, TRANSMAT, XGD)
0007 %   MD = LOADMD(MPC, TRANSMAT, XGD, SD)
0008 %   MD = LOADMD(MPC, TRANSMAT, XGD, SD, CONTAB)
0009 %   MD = LOADMD(MPC, TRANSMAT, XGD, SD, CONTAB, PROFILES)
0010 %   MD = LOADMD(MPC, TRANSMAT, XGD, SD, CONTAB, PROFILES, TRAJDATA)
0011 %   MD = LOADMD(MPC, NT, ...)
0012 %
0013 %   All inputs can have the format described below or can be given as
0014 %   strings containing the name of the MAT-file or M-file that contains the
0015 %   data in the proper format.
0016 %
0017 %   Inputs:
0018 %       MPC:       a standard MATPOWER case struct, optionally with
0019 %                  additional fields such as 'genfuel' and 'i<type>'
0020 %                  NOTE: Bus numbers must be consecutive beginning at 1
0021 %                        (i.e. internal ordering).
0022 %       TRANSMAT:  (optional) NT dimensional cell array of matrices, where
0023 %                  TRANSMAT{t} is an NJ(t) x NJ(t-1) matrix containing the
0024 %                  transition probabilities from period t-1 to period t. The
0025 %                  first element TRANSMAT{1} is a column vector of transition
0026 %                  probabilities from period 0 (NJ(0) = 1) to period 1. For
0027 %                  deterministic cases, TRANSMAT can be specified simply as
0028 %                  an integer NT (number of periods), which gets expanded
0029 %                  internally to a cell array of 1's. Default value is 1.
0030 %       XGD:       (optional) xGenData struct, see LOADXGENDATA for details.
0031 %       SD:        (optional) StorageData struct, see LOADSTORAGEDATA for
0032 %                  details.
0033 %       CONTAB:    (optional) contingency table with master set of
0034 %                  contingencies used for security throughout entire horizon
0035 %       PROFILES:  (optional) a struct array of Profiles (see IDX_PROFILE
0036 %                  and APPLY_PROFLE for details), specifying changes in the
0037 %                  system and operational conditions, xGenData, StorageData
0038 %                  and/or contingencies across time periods and scenarios.
0039 %                  Alternatively, for backward compatibility with the
0040 %                  older centroids format, PROFILES can take the form of
0041 %                  a struct with the following fields:
0042 %                     .wind:  3-dim array (NT x NJ_MAX x num wind sites)
0043 %                     .load:  3-dim array (NT x NJ_MAX x num load zones)
0044 %                  If empty, no changes are made across time.
0045 %       TRAJDATA:  (optional) struct array in same format as PROFILES
0046 %                  specifying a set of trajectories for a stage 2 solution.
0047 %                  The J dimension of the profile in this case indexes the
0048 %                  trajectories.
0049 
0050 % Created by Daniel Munoz-Alvarez (2/28/2013)
0051 
0052 %   MOST
0053 %   Copyright (c) 2013-2016, Power Systems Engineering Research Center (PSERC)
0054 %   by Daniel Munoz-Alvarez and Ray Zimmerman, PSERC Cornell
0055 %
0056 %   This file is part of MOST.
0057 %   Covered by the 3-clause BSD License (see LICENSE file for details).
0058 %   See https://github.com/MATPOWER/most for more info.
0059 
0060 if nargin < 7
0061     trajdatai = [];
0062     if nargin < 6
0063         profilesi = [];
0064         if nargin < 5
0065             contabi = [];
0066             if nargin < 4
0067                 storagei = [];
0068                 if nargin < 3
0069                     xgdi = [];
0070                     if nargin < 2
0071                         transmati = [];
0072                         if nargin < 1
0073                             error('loadmd: MPC is a mandatory argument');
0074                         end
0075                     end
0076                 end
0077             end
0078         end
0079     end
0080 end
0081 
0082 define_constants;
0083 [CT_LABEL, CT_PROB, CT_TABLE, CT_TBUS, CT_TGEN, CT_TBRCH, ...
0084     CT_TAREABUS, CT_TAREAGEN, CT_TAREABRCH, CT_ROW, CT_COL, CT_CHGTYPE, ...
0085     CT_REP, CT_REL, CT_ADD, CT_NEWVAL, CT_TLOAD, CT_TAREALOAD, ...
0086     CT_LOAD_ALL_PQ, CT_LOAD_FIX_PQ, CT_LOAD_DIS_PQ, CT_LOAD_ALL_P, ...
0087     CT_LOAD_FIX_P, CT_LOAD_DIS_P, CT_TGENCOST, CT_TAREAGENCOST, ...
0088     CT_MODCOST_F, CT_MODCOST_X] = idx_ct;
0089 [PR_REP, PR_REL, PR_ADD, PR_TCONT, PR_TYPES, PR_TMPCD,...
0090    PR_TXGD, PR_TCTD, PR_TSTGD, PR_CHGTYPES] = idx_profile;
0091 
0092 % (A) load mandatory arg MPC
0093 
0094 % (A.1) load MATPOWER case
0095 mpc = loadcase(mpci);
0096 
0097 
0098 % (B) read other arguments into struct
0099 
0100 % (B.1) transmat
0101 if isempty(transmati)
0102     transmat = {1};         % default is single period deterministic
0103 elseif isscalar(transmati) && isnumeric(transmati)
0104     transmat = transmati;   % specifies NT
0105 else
0106     type = {'cell'};
0107     transmat = loadgenericdata(transmati, type);
0108     if isempty(transmat)
0109         error('loadmd: must provide a non-empty TRANSMAT cell array')
0110     end
0111 end
0112 
0113 % (B.2) xGenData
0114 type = {'struct'};
0115 fields = {...
0116           'CommitSched', ...
0117           'InitialPg', ...
0118           'RampWearCostCoeff', ...
0119           'PositiveActiveReservePrice', ...
0120           'PositiveActiveReserveQuantity', ...
0121           'NegativeActiveReservePrice', ...
0122           'NegativeActiveReserveQuantity', ...
0123           'PositiveActiveDeltaPrice', ...
0124           'NegativeActiveDeltaPrice', ...
0125           'PositiveLoadFollowReservePrice', ...
0126           'PositiveLoadFollowReserveQuantity', ...
0127           'NegativeLoadFollowReservePrice', ...
0128           'NegativeLoadFollowReserveQuantity', ...
0129           };
0130 xgd = loadgenericdata(xgdi, type, fields);
0131 
0132 
0133 % (B.3) storage
0134 type = {'struct'};
0135 fields = {...
0136           'UnitIdx';...
0137 %           'ExpectedTerminalStorageAim';... optional
0138 %           'ExpectedTerminalStorageMin';... optional
0139 %           'ExpectedTerminalStorageMax';... optional
0140           'InitialStorage';...
0141 %           'InitialStorageLowerBound';... optional
0142 %           'InitialStorageUpperBound';... optional
0143 %           'InitialStorageCost';... optional
0144           'TerminalStoragePrice';...
0145 %           'TerminalChargingPrice0';... optional
0146 %           'TerminalDischargingPrice0';... optional
0147 %           'TerminalChargingPriceK';... optional
0148 %           'TerminalDischargingPriceK';... optional
0149 %           'ExpectedStorageState';... optional
0150 %           'ExpectedStorageDispatch';... optional
0151           'MinStorageLevel';...
0152           'MaxStorageLevel';...
0153 %           'OutEff';... optional
0154 %           'InEff';... optional
0155 %           'LossFactor';... optional
0156 %           'rho';... optional
0157           };
0158 storage = loadgenericdata(storagei, type, fields);
0159 
0160 
0161 % (B.4) contab
0162 type = {'array'};
0163 contab = loadgenericdata(contabi, type);
0164 
0165 
0166 % (B.5) profiles
0167 type = {'struct'};
0168 fields = {'type','table','rows','col','chgtype','values'};
0169 
0170 % Load profiles. If fails to find profiles' fields, then checks whether the
0171 % provided input is in a centroids format. This is obsolete though since
0172 % centroids only supports changes across time for load and wind. Keeping
0173 % just for backard compatibility.
0174 try
0175     profiles = loadgenericdata(profilesi, type, fields);
0176 catch exception
0177     if strcmp(exception.identifier,'loadgenericdata:missingfield')
0178         fields = {'wind', 'load'};
0179         centroids = loadgenericdata(profilesi, type, fields);
0180         if size(centroids.load,3) > 1 % if 3rd-dim = several zones
0181             table = PR_TAREALOAD;
0182             rows = (1:size(centroids.load,3))';
0183         else
0184             table = PR_TLOAD;
0185             rows = 0;
0186         end
0187         profiles = [ centroids2profile(centroids.wind, PR_TGEN, mpc.iwind, PMAX, PR_REL) ;...
0188                      centroids2profile(centroids.load, table, rows, CT_LOAD_ALL_P, PR_REL) ;
0189                    ];
0190     else
0191         rethrow(exception);
0192     end
0193 end
0194 
0195 
0196 % (B.6) trajdata
0197 type = {'struct'};
0198 fields = {'type','table','rows','col','chgtype','values'};
0199 
0200 % Load trajdata works as load profile. See details above regarding the
0201 % backward compatibility to use centroids format.
0202 try
0203     trajdata = loadgenericdata(trajdatai, type, fields);
0204 catch exception
0205     if strcmp(exception.identifier,'loadgenericdata:missingfield')
0206         fields = {'wind', 'load'};
0207         trajdatacentroids = loadgenericdata(trajdatai, type, fields);
0208         if size(trajdatacentroids.load,3) > 1 % if 3rd-dim = several zones
0209             table = PR_TAREALOAD;
0210             rows = (1:size(trajdatacentroids.load,3))';
0211         else
0212             table = PR_TLOAD;
0213             rows = 0;
0214         end
0215         trajdata = [ centroids2profile(trajdatacentroids.wind, PR_TGEN, mpc.iwind, PMAX, PR_REL) ;...
0216                      centroids2profile(trajdatacentroids.load, table, rows, CT_LOAD_ALL_P, PR_REL) ;
0217                    ];
0218     else
0219         rethrow(exception);
0220     end
0221 end
0222 if ~isempty(trajdata) % trajdatai not provided causes info regarding second stg not to be loaded
0223     second = true;
0224 else
0225     second = false;
0226 end
0227 
0228 
0229 % (C) verify consistency of inputs and truncate them to run algorithm when possible
0230 
0231 % (C.0) Initialize md struct
0232 md = md_init;
0233 
0234 
0235 % (C.1) Obtain basic dimensions from the most restrictive input data
0236 if iscell(transmat)
0237     nt = length(transmat);
0238 else                            % expand NT to full deterministic TRANSMAT
0239     nt = transmat;
0240     transmat = ones(1, nt);
0241     transmat = mat2cell(transmat, 1, transmat);
0242 end
0243 
0244 nj = zeros(nt,1);
0245 for t = 1:nt
0246     nj(t) = size(transmat{t},1);
0247 end
0248 nj_max = max(nj);
0249 
0250 nb = size(mpc.bus,1);           % num buses
0251 ng = size(mpc.gen,1);           % num gen
0252 if isfield(mpc, 'iwind')
0253     nw = size(mpc.iwind,1);     % num wind gen
0254 else
0255     nw = 0;                     % num wind gen
0256 end
0257 if isfield(mpc, 'iess')
0258     ns = size(mpc.iess,1);      % num ess gen
0259 else
0260     ns = 0;                     % num ess gen
0261 end
0262 nprof = size(profiles,1);       % num of profiles (wind profile, load profile, ice storage profile, etc.)
0263 
0264 if second
0265     nprof2 = size(trajdata,1);              % Determined as num of profile elements (structs) there are in trajdata
0266     ntraj = size(trajdata(1).values,2);     % Determined as num of trajectories that the first trajectory profile has
0267 end
0268 
0269 
0270 % (C.2) Store basic dimensions not imposed implicitly by inputs
0271     %     themselves in most(.)
0272 md.idx.nt = nt;
0273 
0274 
0275 % (C.3) Verify that obtained basic dimensions are valid
0276 if any(nj < 1)  % verify nj dimensions
0277     error('loadmd: number of scenarios nj must be at least 1');
0278 end
0279 
0280 if nt < 1       % need at least one time period
0281     error('loadmd: number of time periods nt must be at least 1');
0282 end
0283 
0284 
0285 % (C.4) Look for empty input data and assign well-formatted default data
0286     % which should be assigned in case the corresponding variable is empty.
0287 
0288 % (C.4.0) mpc
0289 %% check that bus numbers are equal to indices to bus (one set of bus numbers)
0290 if any(mpc.bus(:, BUS_I) ~= (1:nb)')
0291     error('loadmd: buses must be numbered consecutively in MPC.bus matrix; use ext2int() to convert to internal ordering')
0292 end
0293 
0294 % (C.4.1) transmat
0295     % handled previously so dimensions could be set in (C.1)
0296 
0297 % (C.4.2) xGenData
0298 if isempty(xgd)     % assign the default input
0299     xgd = loadxgendata([], mpc);
0300 end
0301 
0302 % (C.4.3) storage
0303 if ns == 0  % No ess units
0304     storage = [];   % storage struct ignored if provided
0305 else
0306     if isempty(storage)
0307         error('loadmd: storage struct cannot be empty when MPC contains storage units');
0308     end
0309     % let most() assign defaults
0310     if ~isfield(storage,'OutEff')
0311         storage.OutEff = [];
0312     end
0313     if ~isfield(storage,'InEff')
0314         storage.InEff = [];
0315     end
0316     if ~isfield(storage,'LossFactor')
0317         storage.LossFactor = [];
0318     end
0319     if ~isfield(storage,'rho')
0320         storage.rho = [];
0321     end
0322 end
0323 
0324 % (C.4.4) contab
0325 
0326 % (C.4.5) profiles
0327     % Optional: An empty profiles struct array means no differences in the
0328     % operating conditions across time periods or scenarios.
0329 
0330 % (C.4.6) options
0331 
0332 % (C.4.7) trajdata
0333     % Optional, if not given (empty) then it is not used
0334 
0335 
0336 % (C.5) Verify consistency of input dimensions
0337 
0338 % (C.5.1) transmat
0339 if length(transmat) < nt   % verify transmat dim is nt (redundant since nt is defined with transmat)
0340     error('loadmd: nt (= %d) has been modified and no longer matches transmat time dimension (%d)', nt, length(transmat));
0341 else        % verify consistency of transmat with nj(t) (redundant since nj is defined with transmat)
0342     if size(transmat{1}, 1) ~= nj(1)
0343         error('loadmd: # of scenarios in t=1, nj(1) = %d, does not match # of rows in transmat{1} (%d)', nj(1), size(transmat{1}, 1));
0344     end
0345     if nt > 1
0346         for t = 2:nt
0347             if any(size(transmat{t}) ~= [nj(t) nj(t-1)])
0348                 error('loadmd: dimensions of transmat{%d} (%d x %d) inconsistent with nj(%d) x nj(%d) (%d x %d)', ...
0349                     t, size(transmat{t}, 1), size(transmat{t}, 2), t, t-1, nj(t), nj(t-1));
0350             end
0351         end
0352     end
0353 end
0354 
0355 % (C.5.2) xGenData
0356 if any( [size(xgd.CommitSched, 1) ...
0357          size(xgd.InitialPg, 1) ...
0358          size(xgd.RampWearCostCoeff, 1) ...
0359          size(xgd.PositiveActiveReserveQuantity, 1) ...
0360          size(xgd.NegativeActiveReservePrice, 1) ...
0361          size(xgd.NegativeActiveReserveQuantity, 1) ...
0362          size(xgd.PositiveActiveDeltaPrice, 1) ...
0363          size(xgd.NegativeActiveDeltaPrice, 1) ...
0364          size(xgd.PositiveLoadFollowReservePrice, 1) ...
0365          size(xgd.PositiveLoadFollowReserveQuantity, 1) ...
0366          size(xgd.NegativeLoadFollowReservePrice, 1) ...
0367          size(xgd.NegativeLoadFollowReserveQuantity, 1) ...
0368          ] ~= ng )
0369      error('loadmd: 1st dimension inconsistency in field of xGenData')
0370 end
0371 
0372 % (C.5.3) storage
0373 if ~isempty(storage)
0374     if length(storage.UnitIdx) ~= length(mpc.iess)
0375         error('loadmd: dimensions of storage.UnitIdx (%d) and mpc.iess (%d) must match', length(storage.UnitIdx), length(mpc.iess));
0376     end
0377 end
0378 
0379 % (C.5.4) contab
0380 size_contab = size(contab);
0381 if ~isempty(contab) && (length(size_contab) ~= 2 || size_contab(2) ~= 7)
0382     error('loadmd: contab must be matrix with 7 columns');
0383 end
0384 
0385 % (C.5.5) profiles
0386 for p = 1:nprof
0387     if ~isnumeric(profiles(p).values)
0388         error('loadmd: profiles(%d).values is required to be a numeric array', p);
0389     end
0390     if length(size(profiles(p).values)) > 3
0391         error('loadmd: profiles(%d).values must have no more than 3 dimensions', p);
0392     end
0393     if ~( size(profiles(p).values, 1) == 1 ||...
0394           size(profiles(p).values, 1) >= nt )
0395         error('loadmd: time dimension of profiles(%d).values (%d) must be 1 or >= nt = %d', p, size(profiles(p).values, 1), nt);
0396     end
0397     if ~( size(profiles(p).values, 2) == 1 ||...
0398           size(profiles(p).values, 2) == nj_max )
0399         error('loadmd: scenarios dimension of profiles(%d).values (%d) must be 1 or nj_max = %d', p, size(profiles(p).values, 2), nj_max);
0400     end
0401     if ~( size(profiles(p).values, 3) == 1 ||...
0402           size(profiles(p).values, 3) == length(profiles(p).rows) )
0403         error('loadmd: 3rd dimension of profiles(%d).values (%d) must be 1 or %d (length of profiles(%d).rows)', p, size(profiles(p).values, 3), length(profiles(p).rows), p);
0404     end
0405     if ~any(strcmp(profiles(p).type, PR_TYPES))
0406         error('loadmd: profiles(%d).type not supported', p);
0407     end
0408     if ~(isscalar(profiles(p).table) || ischar(profiles(p).table))
0409         error('loadmd: profiles(%d).table must be either scalar or string', p);
0410     end
0411     if ~isvector(profiles(p).rows)
0412         error('loadmd: profiles(%d).rows must be a vector', p);
0413     end
0414     if ~isscalar(profiles(p).col)
0415         error('loadmd: profiles(%d).col must be scalar', p);
0416     end
0417     if ~any(profiles(p).chgtype == PR_CHGTYPES)
0418         error('loadmd: profiles(%d).chgtype not supported', p);
0419     end
0420 end
0421 
0422 % (C.5.6) options
0423 
0424 % (C.5.7) trajdata
0425 if second
0426     for p = 1:nprof2
0427         if ~isnumeric(trajdata(p).values)
0428             error('loadmd: trajdata(%d).values is required to be a numeric array', p);
0429         end
0430         if length(size(trajdata(p).values)) > 3
0431             error('loadmd: trajdata(%d).values must have no more than 3 dimensions', p);
0432         end
0433         if ~( size(trajdata(p).values, 1) == 1 ||...
0434               size(trajdata(p).values, 1) >= nt )
0435             error('loadmd: time dimension of trajdata(%d).values (%d) must be 1 or >= nt = %d', p, size(trajdata(p).values, 1), nt);
0436         end
0437         if ~( size(trajdata(p).values, 2) == 1 ||...
0438               size(trajdata(p).values, 2) == ntraj )
0439             error('loadmd: scenarios dimension of trajdata(%d).values (%d) must be 1 or ntraj = %d', p, size(trajdata(p).values, 2), ntraj);
0440         end
0441         if ~( size(trajdata(p).values, 3) == 1 ||...
0442               size(trajdata(p).values, 3) == length(trajdata(p).rows) )
0443             error('loadmd: 3rd dimension of trajdata(%d).values (%d) must be 1 or %d (length of trajdata(%d).rows)', p, size(trajdata(p).values, 3), length(trajdata(p).rows), p);
0444         end
0445         if ~any(strcmp(trajdata(p).type, PR_TYPES))
0446             error('loadmd: trajdata(%d).type not supported', p);
0447         end
0448         if ~(isscalar(trajdata(p).table) || ischar(trajdata(p).table))
0449             error('loadmd: trajdata(%d).table must be either scalar or string', p);
0450         end
0451         if ~isvector(trajdata(p).rows)
0452             error('loadmd: trajdata(%d).rows must be a vector', p);
0453         end
0454         if ~isscalar(trajdata(p).col)
0455             error('loadmd: trajdata(%d).col must be scalar', p);
0456         end
0457         if ~any(trajdata(p).chgtype == PR_CHGTYPES)
0458             error('loadmd: trajdata(%d).chgtype not supported', p);
0459         end
0460     end
0461 end
0462 
0463 
0464 % (C.6) Truncate all input data to make consistent basic dimensions
0465     % Not necessary for transmat (since it defines nt)
0466 
0467 % (C.6.1) transmat
0468 transmat = transmat(1:nt);  % redundant, since nt is defined by transmat
0469 % (C.6.2) xGenData
0470 % (C.6.3) storage
0471 % (C.5.4) contab
0472 % (C.6.5) profiles
0473 for p = 1:nprof
0474     profiles(p).values = profiles(p).values(1:nt,:,:);
0475 end
0476 % (C.6.6) options
0477 % (C.6.7) trajdata
0478 if second
0479     for p = 1:nprof2
0480         trajdata(p).values = trajdata(p).values(1:nt,1:ntraj,:);
0481     end
0482 end
0483 
0484 % (C.7) Put all necessary info into md struct in order to run most()
0485 %       Here, all the profiles are "expanded" and applied to data before
0486 %       the latter is actually assigned to md.
0487 %       Moreover, all info required to run mpsopfl2 is loaded into md if
0488 %       second == 1.
0489 
0490 % (C.7.0) transmat: assign transition probability matrices to md struct
0491 for t = 1:nt
0492     md.tstep(t).TransMat = transmat{t};
0493 end
0494 
0495 % (C.7.1) mpc: assign mpc to md struct
0496 md.mpc = mpc;
0497 
0498 % (C.7.2) profiles: build operation conditions contab per period per scenario
0499 
0500 % (C.7.2.1) transform profiles of type mpcData into contabs
0501 optab = cell(nt,nj_max);
0502 for p = 1:nprof
0503     if strcmp(profiles(p).type, 'mpcData')
0504 %       Profiles of type mpcData need to be passed along to most()
0505 %       as contingency-like tables describing the operation
0506 %       conditions for each time period and each scenario. Those
0507 %       contabs are stored in the OpCondSched struct array.
0508         optab = apply_profile(profiles(p), optab);
0509     end
0510 end
0511 
0512 % (C.7.2.2) store 'operation conditions' contabs into md
0513 for t = 1:nt
0514     for j = 1:nj(t)
0515         md.tstep(t).OpCondSched(j).tab = optab{t,j};
0516     end
0517 end
0518     
0519 % (C.7.2.3) store profiles into md perhaps for results
0520 % md.profiles = profiles;   % For ploting purposes only (need wind profile in mpsopf_plots1)
0521 
0522 % (C.7.3) storage: superimpose given storage struct into initialized
0523 %                  storage struct
0524 
0525 % (C.7.3.1) assign fields given in 'storage' input to initialized 'Storage' struct
0526 if ~isempty(storage)
0527     fields = { ...
0528         'UnitIdx', ...
0529         'ExpectedTerminalStorageAim', ...
0530         'ExpectedTerminalStorageMin', ...
0531         'ExpectedTerminalStorageMax', ...
0532         'InitialStorage', ...
0533         'InitialStorageLowerBound', ...
0534         'InitialStorageUpperBound', ...
0535         'InitialStorageCost', ...
0536         'TerminalStoragePrice', ...
0537         'TerminalChargingPrice0', ...
0538         'TerminalDischargingPrice0', ...
0539         'TerminalChargingPriceK', ...
0540         'TerminalDischargingPriceK', ...
0541         'ExpectedStorageState', ...
0542         'ExpectedStorageDispatch', ...
0543         'MinStorageLevel', ...
0544         'MaxStorageLevel', ...
0545         'OutEff', ...
0546         'InEff', ...
0547         'LossFactor', ...
0548         'rho', ...
0549     };
0550     for f = 1:length(fields)
0551         ff = fields{f};
0552         if isfield(storage, ff)
0553             md.Storage.(ff) = storage.(ff);
0554         end
0555     end
0556 end
0557 
0558 % (C.7.3.2) apply storage profiles
0559 if ns > 0
0560     for p = 1:nprof
0561         if strcmp(profiles(p).type, 'StorageData')
0562             md.Storage = apply_profile(profiles(p), md.Storage, ns);
0563         end
0564     end
0565 end
0566 
0567 % (C.7.4) options: assign options related variables
0568 
0569 % (C.7.5) xGenData: assign xgd related variables
0570 for p = 1:nprof
0571     if strcmp(profiles(p).type, 'xGenData')
0572         xgd = apply_profile(profiles(p), xgd, ng);
0573     end
0574 end
0575 
0576 if isfield(xgd, 'CommitKey') && ~isempty(xgd.CommitKey)
0577     UC = 1;
0578 else
0579     UC = 0;
0580 end
0581 
0582 %% fields with no time dimension
0583 %% in md
0584 md.InitialPg = xgd.InitialPg;
0585 if isfield(xgd, 'TerminalPg')       %% optional, deprecated
0586     md.TerminalPg = xgd.TerminalPg;
0587 end
0588 %% in md.UC
0589 if UC
0590     md.UC.InitialState    = xgd.InitialState;
0591     md.UC.MinUp           = xgd.MinUp;
0592     md.UC.MinDown         = xgd.MinDown;
0593 end
0594 
0595 %% fields in md
0596 fields = {'RampWearCostCoeff'};
0597 for f = 1:length(fields)
0598     ff = fields{f};
0599     if size(xgd.(ff), 2) == 1       %% xGenData contains 1 column
0600         for t = 1:nt
0601             md.(ff)(:,t)   = xgd.(ff);
0602         end
0603     elseif size(xgd.(ff), 2) == nt  %% xGenData contains nt columns
0604         md.(ff)            = xgd.(ff);
0605     else
0606         error('loadmd: number of columns in XGD.%s must be 1 or %d', ff, nt);
0607     end
0608 end
0609 
0610 %% fields in md.UC
0611 fields = {'CommitSched'};
0612 if UC                               %% optional
0613     fields = {fields{:}, 'CommitKey'};
0614 end
0615 for f = 1:length(fields)
0616     ff = fields{f};
0617     if size(xgd.(ff), 2) == 1       %% xGenData contains 1 column
0618         for t = 1:nt
0619             md.UC.(ff)(:,t)   = xgd.(ff);
0620         end
0621     elseif size(xgd.(ff), 2) == nt  %% xGenData contains nt columns
0622         md.UC.(ff)            = xgd.(ff);
0623     else
0624         error('loadmd: number of columns in XGD.UC.%s must be 1 or %d', ff, nt);
0625     end
0626 end
0627 
0628 %% fields in offer
0629 fields = {
0630     'PositiveActiveReservePrice', 'PositiveActiveReserveQuantity', ...
0631     'NegativeActiveReservePrice', 'NegativeActiveReserveQuantity', ...
0632     'PositiveActiveDeltaPrice', 'NegativeActiveDeltaPrice', ...
0633     'PositiveLoadFollowReservePrice', 'PositiveLoadFollowReserveQuantity', ...
0634     'NegativeLoadFollowReservePrice', 'NegativeLoadFollowReserveQuantity', ...
0635 };
0636 for f = 1:length(fields)
0637     ff = fields{f};
0638     if size(xgd.(ff), 2) == 1       %% xGenData contains 1 column
0639         for t = 1:nt
0640             md.offer(t).(ff)  = xgd.(ff);
0641         end
0642     elseif size(xgd.(ff), 2) == nt  %% xGenData contains nt columns
0643         for t = 1:nt
0644             md.offer(t).(ff)  = xgd.(ff)(:, t);
0645         end
0646     else
0647         error('loadmd: number of columns in XGD.%s must be 1 or %d', ff, nt);
0648     end
0649 end
0650 
0651 % (C.7.6) contab: assign contingency tables per period per scenario to md struct
0652 ct_subset = ones(nt, nj_max, size(contab,1)); % subset of contingencies
0653 %                                               in contab to be apply
0654 %                                               per scenario per time
0655 %                                               period.
0656 for p = 1:nprof
0657     if strcmp(profiles(p).type, 'ContingencyData')
0658         ct_subset = apply_profile(profiles(p), ct_subset, ncont);
0659     end
0660 end
0661 
0662 % Assign subset of contingencies indicated by profile ct_subset
0663 for t = 1:nt
0664     for j = 1:nj(t)
0665         md.cont(t,j).contab = contab(squeeze(ct_subset(t,j,:)) == 1,:);
0666     end
0667 end
0668 
0669 
0670 % (C.7.7) trajdata: second stage related data
0671 %       Although the data necessary for running the second stg is
0672 %       loaded here, a first stage still needs to be ran before the
0673 %       second stg can actually be ran since results from the former
0674 %       are needed for the latter.
0675 if second
0676 
0677     optab2 = cell(nt,ntraj);
0678 
0679     % Modifications regarding profiles
0680     % (which should not include changes to conventional gen, i.e.,
0681     % gens that are neither wind units nor loads because it could
0682     % generate conflicts when changing the same unit with more than 1
0683     % contingency-like changes subsequently in the mpsopfl2 fcn)
0684     for p = 1:nprof2
0685         optab2 = profile2contabs(optab2, trajdata(p));
0686     end
0687 
0688 
0689     for t = 1:nt
0690         for j = 1:ntraj
0691             md.second.tstep(t).OpCondSched(j).tab = optab2{t,j};
0692         end
0693     end
0694 
0695 end

Generated on Mon 24-Jun-2019 15:58:45 by m2html © 2005