forked from MATPOWER/matpower
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathadd_userfcn.m
130 lines (126 loc) · 5.07 KB
/
add_userfcn.m
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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
function mpc = add_userfcn(mpc, stage, fcn, args, allow_multiple)
%ADD_USERFCN Appends a userfcn to the list to be called for a case.
%
% MPC = ADD_USERFCN(MPC, STAGE, FCN)
% MPC = ADD_USERFCN(MPC, STAGE, FCN, ARGS)
% MPC = ADD_USERFCN(MPC, STAGE, FCN, ARGS, ALLOW_MULTIPLE)
%
% A userfcn is a callback function that can be called automatically by
% MATPOWER at one of various stages in a simulation.
%
% MPC : the case struct
% STAGE : the name of the stage at which this function should be
% called: ext2int, formulation, int2ext, printpf
% FCN : the name of the userfcn
% ARGS : (optional) the value to be passed as an argument to the
% userfcn (typically a struct)
% ALLOW_MULTIPLE : (optional) if TRUE, allows the same function to
% be added more than once.
%
% Currently there are 5 different callback stages defined. Each stage has
% a name, and by convention, the name of a user-defined callback function
% ends with the name of the stage. The following is a description of each
% stage, when it is called and the input and output arguments which vary
% depending on the stage. The reserves example (see RUNOPF_W_RES) is used
% to illustrate how these callback userfcns might be used.
%
% 1. ext2int
%
% Called from EXT2INT immediately after the case is converted from
% external to internal indexing. Inputs are a MATPOWER case struct (MPC),
% freshly converted to internal indexing and any (optional) ARGS value
% supplied via ADD_USERFCN. Output is the (presumably updated) MPC. This is
% typically used to reorder any input arguments that may be needed in
% internal ordering by the formulation stage.
%
% E.g. mpc = userfcn_reserves_ext2int(mpc, args)
%
% 2. formulation
%
% Called from OPF after the OPF Model (OM) object has been initialized
% with the standard OPF formulation, but before calling the solver. Inputs
% are the OM object and any (optional) ARGS supplied via ADD_USERFCN.
% Output is the OM object. This is the ideal place to add any additional
% vars, constraints or costs to the OPF formulation.
%
% E.g. om = userfcn_reserves_formulation(om, args)
%
% 3. int2ext
%
% Called from INT2EXT immediately before the resulting case is converted
% from internal back to external indexing. Inputs are the RESULTS struct
% and any (optional) ARGS supplied via ADD_USERFCN. Output is the RESULTS
% struct. This is typically used to convert any results to external
% indexing and populate any corresponding fields in the RESULTS struct.
%
% E.g. results = userfcn_reserves_int2ext(results, args)
%
% 4. printpf
%
% Called from PRINTPF after the pretty-printing of the standard OPF
% output. Inputs are the RESULTS struct, the file descriptor to write to,
% a MATPOWER options struct, and any (optional) ARGS supplied via
% ADD_USERFCN. Output is the RESULTS struct. This is typically used for
% any additional pretty-printing of results.
%
% E.g. results = userfcn_reserves_printpf(results, fd, mpopt, args)
%
% 5. savecase
%
% Called from SAVECASE when saving a case struct to an M-file after
% printing all of the other data to the file. Inputs are the case struct,
% the file descriptor to write to, the variable prefix (typically 'mpc.')
% and any (optional) ARGS supplied via ADD_USERFCN. Output is the case
% struct. This is typically used to write any non-standard case struct
% fields to the case file.
%
% E.g. mpc = userfcn_reserves_printpf(mpc, fd, prefix, args)
%
% See also RUN_USERFCN, REMOVE_USERFCN, TOGGLE_RESERVES, TOGGLE_IFLIMS,
% TOGGLE_DCLINE, TOGGLE_SOFTLIMS, and RUNOPF_W_RES.
% MATPOWER
% Copyright (c) 2009-2016, Power Systems Engineering Research Center (PSERC)
% by Ray Zimmerman, PSERC Cornell
%
% This file is part of MATPOWER.
% Covered by the 3-clause BSD License (see LICENSE file for details).
% See http://www.pserc.cornell.edu/matpower/ for more info.
if nargin < 5
allow_multiple = 0;
if nargin < 4
args = [];
end
end
switch stage
case {'ext2int', 'formulation', 'int2ext', 'printpf', 'savecase'}
%% ok
otherwise
error('add_userfcn : ''%s'' is not the name of a valid callback stage\n', stage);
end
n = 1;
if isfield(mpc, 'userfcn')
if isfield(mpc.userfcn, stage)
n = length(mpc.userfcn.(stage)) + 1;
if ~allow_multiple
if have_fcn('octave')
fcn_info = functions(fcn);
for k = 1:n-1
cb_info = functions(mpc.userfcn.(stage)(k).fcn);
if strcmp(cb_info.function, fcn_info.function)
error('add_userfcn: the function ''%s'' has already been added', func2str(fcn));
end
end
else
for k = 1:n-1
if isequal(mpc.userfcn.(stage)(k).fcn, fcn)
error('add_userfcn: the function ''%s'' has already been added', func2str(fcn));
end
end
end
end
end
end
mpc.userfcn.(stage)(n).fcn = fcn;
if ~isempty(args)
mpc.userfcn.(stage)(n).args = args;
end