Skip to content

Commit a562713

Browse files
committed
Update ports from DSS-Python 0.13, integrating our base library, DSS C-API 0.13.
- add missing file - DSS.AdvancedTypes mode: when enabled, can return complex numbers and matrices - DSS.CompatFlags: some toggles for compatibility with the official OpenDSS on some specific points. - DSS.AllowDOScmd: toggle running system commands from DSS scripts - DSS.COMErrorResults: toggle returning empty "[]" vs "[0]" etc. - fix many docstring typos - fix some arrays of strings: some functions were broken during the DSSContext migration. - use enums for some properties: easier to read, more maintainable.
1 parent 3a0450d commit a562713

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+1001
-216
lines changed

+DSS_MATLAB/APIUtil.m

Lines changed: 83 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
libname
1010
dssctx
1111
is_prime
12+
allow_complex
1213
end
1314
methods
1415
function obj = APIUtil(varargin)
@@ -19,11 +20,14 @@
1920
else
2021
obj.libname = 'dss_capi';
2122
end
22-
2323
MfilePath = fileparts(mfilename('fullpath'));
2424
DLLfilePath = fullfile(MfilePath, obj.libname);
2525
PropertiesMOfilePath = fullfile(MfilePath, 'messages', 'properties-en-US.mo');
2626
DSS_MATLAB.librefcount(1);
27+
obj.allow_complex = false;
28+
if (nargin > 1) && (varargin{2})
29+
obj.allow_complex = true;
30+
end
2731
if libisloaded(obj.libname)
2832
if (nargin > 0) && (varargin{1} ~= 0)
2933
obj.dssctx = calllib(obj.libname, 'ctx_New');
@@ -95,44 +99,111 @@ function delete(obj)
9599
% setdatatype(obj.DataPtr_PInteger, 'int32PtrPtr', 1);
96100
% setdatatype(obj.DataPtr_PByte, 'int8PtrPtr', 1);
97101

98-
setdatatype(obj.CountPtr_PDouble, 'int32Ptr', 2);
99-
setdatatype(obj.CountPtr_PInteger, 'int32Ptr', 2);
100-
setdatatype(obj.CountPtr_PByte, 'int32Ptr', 2);
102+
setdatatype(obj.CountPtr_PDouble, 'int32Ptr', 4);
103+
setdatatype(obj.CountPtr_PInteger, 'int32Ptr', 4);
104+
setdatatype(obj.CountPtr_PByte, 'int32Ptr', 4);
101105
end
102106

103107

104108
function result = get_float64_gr_array(obj)
105109
data = calllib(obj.libname, 'ctx_DSS_GR_DataPtr_PDouble', obj.dssctx);
106-
setdatatype(data, 'doublePtr', 1, obj.CountPtr_PDouble.Value(1));
110+
cnt = obj.CountPtr_PDouble.Value;
111+
setdatatype(data, 'doublePtr', 1, cnt(1));
107112
result = data.Value;
113+
if obj.allow_complex && (cnt(4) ~= 0)
114+
% If the last element is filled, we have a matrix. Otherwise, the
115+
% matrix feature is disabled or the result is indeed a vector
116+
result = reshape(result, [cnt(3), cnt(4)]);
117+
end
108118
end
109119

120+
function result = get_complex128_gr_array(obj)
121+
if ~obj.allow_complex
122+
result = obj.get_float64_gr_array();
123+
return
124+
end
125+
126+
% Currently we use the same as API as get_float64_array, may change later
127+
data = calllib(obj.libname, 'ctx_DSS_GR_DataPtr_PDouble', obj.dssctx);
128+
cnt = obj.CountPtr_PDouble.Value;
129+
setdatatype(data, 'doublePtr', 1, cnt(1));
130+
result = data.Value(1:2:end) + 1j * data.Value(2:2:end);
131+
if obj.allow_complex && (cnt(4) ~= 0)
132+
% If the last element is filled, we have a matrix. Otherwise, the
133+
% matrix feature is disabled or the result is indeed a vector
134+
result = reshape(result, [cnt(3), cnt(4)]);
135+
end
136+
end
137+
138+
function result = get_complex128_gr_simple(obj)
139+
if ~obj.allow_complex
140+
result = obj.get_float64_gr_array();
141+
return
142+
end
143+
144+
% Currently we use the same as API as get_float64_array, may change later
145+
data = calllib(obj.libname, 'ctx_DSS_GR_DataPtr_PDouble', obj.dssctx);
146+
cnt = obj.CountPtr_PDouble.Value;
147+
assert(cnt(1) == 2, 'Unexpected number of elements returned by API');
148+
setdatatype(data, 'doublePtr', 1, 2);
149+
result = data.Value(1) + 1j * data.Value(2);
150+
end
151+
110152
function result = get_int32_gr_array(obj)
111153
data = calllib(obj.libname, 'ctx_DSS_GR_DataPtr_PInteger', obj.dssctx);
112-
setdatatype(data, 'int32Ptr', 1, obj.CountPtr_PInteger.Value(1));
154+
cnt = obj.CountPtr_PInteger.Value;
155+
setdatatype(data, 'int32Ptr', 1, cnt);
113156
result = data.Value;
157+
if obj.allow_complex && (cnt(4) ~= 0)
158+
% If the last element is filled, we have a matrix. Otherwise, the
159+
% matrix feature is disabled or the result is indeed a vector
160+
result = reshape(result, [cnt(3), cnt(4)]);
161+
end
114162
end
115163

116164
function result = get_int8_gr_array(obj)
117165
data = calllib(obj.libname, 'ctx_DSS_GR_DataPtr_PByte', obj.dssctx);
118-
setdatatype(data, 'int8Ptr', 1, obj.CountPtr_PByte.Value(1));
166+
cnt = obj.CountPtr_PByte.Value;
167+
setdatatype(data, 'int8Ptr', 1, cnt(1));
119168
result = data.Value;
169+
if obj.allow_complex && (cnt(4) ~= 0)
170+
% If the last element is filled, we have a matrix. Otherwise, the
171+
% matrix feature is disabled or the result is indeed a vector
172+
result = reshape(result, [cnt(3), cnt(4)]);
173+
end
120174
end
121175

122176
function result = get_string_array(obj, funcname, varargin)
123177
dataPointer = libpointer('voidPtr', 0);
124-
countPointer = libpointer('int32Ptr', [0, 0]);
178+
countPointer = libpointer('int32Ptr', [0, 0, 0, 0]);
125179
calllib(obj.libname, funcname, obj.dssctx, dataPointer, countPointer, varargin{:});
126180
result = cell(countPointer.Value(1), 1);
127181
for i=1:countPointer.Value(1)
128182
result(i) = cellstr(calllib(obj.libname, 'DSS_Get_PAnsiChar', dataPointer, i - 1));
129183
end
130184
calllib(obj.libname, 'DSS_Dispose_PPAnsiChar', dataPointer, countPointer.Value(2));
131185
end
132-
186+
187+
function obj = set_string_array(obj, funcname, Value)
188+
calllib(obj.libname, funcname, obj.dssctx, Value, numel(Value));
189+
end
190+
191+
function obj = set_complex128_simple(obj, funcname, value)
192+
if ~isreal(value)
193+
assert(length(value) ~= 1, 'A single complex number or a pair of reals was expected');
194+
calllib(obj.libname, funcname, obj.dssctx, value, 2);
195+
return
196+
end
197+
assert((length(value) == 1) || (length(value) == 2), 'A single complex number or a pair of reals was expected');
198+
if (length(value) ~= 2)
199+
value = [value; 0];
200+
end
201+
calllib(obj.libname, funcname, obj.dssctx, value, 2);
202+
end
203+
133204
% function result = get_int8_array(obj, funcname, varargin)
134205
% dataPointer = libpointer('int8PtrPtr');
135-
% countPointer = libpointer('int32Ptr', [0, 0]);
206+
% countPointer = libpointer('int32Ptr', [0, 0, 0, 0]);
136207
% calllib(obj.libname, funcname, dataPointer, countPointer, varargin{:});
137208
% dataPointer.Value
138209
% setdatatype(dataPointer.Value, 'int8Ptr', 1, countPointer.Value(1));
@@ -143,7 +214,7 @@ function delete(obj)
143214

144215
% function result = get_int32_array(obj, funcname, varargin)
145216
% dataPointer = libpointer('int32PtrPtr');
146-
% countPointer = libpointer('int32Ptr', [0, 0]);
217+
% countPointer = libpointer('int32Ptr', [0, 0, 0, 0]);
147218
% calllib(obj.libname, funcname, dataPointer, countPointer, varargin{:});
148219
% setdatatype(dataPointer.Value, 'int32Ptr', 1, countPointer.Value(1));
149220
% result = dataPointer.Value;
@@ -152,7 +223,7 @@ function delete(obj)
152223

153224
% function result = get_float64_array(obj, funcname, varargin)
154225
% dataPointer = libpointer('doublePtrPtr');
155-
% countPointer = libpointer('int32Ptr', [0, 0]);
226+
% countPointer = libpointer('int32Ptr', [0, 0, 0, 0]);
156227
% calllib(obj.libname, funcname, dataPointer, countPointer, varargin{:});
157228
% setdatatype(dataPointer.Value, 'doublePtr', 1, countPointer.Value(1));
158229
% result = dataPointer.Value;

+DSS_MATLAB/ControlModes.m

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
classdef(Enumeration) ControlModes < int32
2+
% ControlModes: enumerated values for DSS.Solution.ControlMode
3+
%
4+
% Values:
5+
% Static(0): Control Mode option - Static
6+
% Event(1): Control Mode Option - Event driven solution mode
7+
% Time(2): Control mode option - Time driven mode
8+
% Multirate(3): Control mode option - Multirate mode
9+
% Off(-1): Control Mode OFF
10+
11+
enumeration
12+
Static(0) % Control Mode option - Static
13+
Event(1) % Control Mode Option - Event driven solution mode
14+
Time(2) % Control mode option - Time driven mode
15+
Multirate(3) % Control mode option - Multirate mode
16+
Off(-1) % Control Mode OFF
17+
end
18+
end

+DSS_MATLAB/DSSCompatFlags.m

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
classdef(Enumeration) DSSCompatFlags < int32
2+
% DSSCompatFlags: enumerated flags for DSS.CompatFlags
3+
%
4+
% Values:
5+
% NoSolverFloatChecks(0x00000001)
6+
% BadPrecision(0x00000002)
7+
% InvControl9611(0x00000004)
8+
%
9+
% Descriptions:
10+
%
11+
% NoSolverFloatChecks:
12+
% If enabled, don't check for NaNs in the inner solution loop.
13+
% This can lead to various errors.
14+
% This flag is useful for legacy applications that don't handle OpenDSS API errors properly.
15+
% Through the development of DSS Extensions, we noticed this is actually a quite common issue.
16+
%
17+
% BadPrecision:
18+
% If enabled, toggle worse precision for certain aspects of the engine. For example, the sequence-to-phase
19+
% (`As2p`) and sequence-to-phase (`Ap2s`) transform matrices. On DSS C-API, we fill the matrix explicitly
20+
% using higher precision, while numerical inversion of an initially worse precision matrix is used in the
21+
% official OpenDSS. We will introduce better precision for other aspects of the engine in the future,
22+
% so this flag can be used to toggle the old/bad values where feasible.
23+
%
24+
% InvControl9611:
25+
% Toggle some InvControl behavior introduced in OpenDSS 9.6.1.1. It could be a regression
26+
% but needs further investigation, so we added this flag in the time being.
27+
28+
29+
enumeration
30+
NoSolverFloatChecks(0x00000001)
31+
BadPrecision(0x00000002)
32+
InvControl9611(0x00000004)
33+
end
34+
end

+DSS_MATLAB/GeneratorStatus.m

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
classdef(Enumeration) GeneratorStatus < int32
2+
% GeneratorStatus: enumerated values for Loads.Status
3+
%
4+
% Values:
5+
% Variable(0)
6+
% Fixed(1)
7+
8+
enumeration
9+
Variable(0)
10+
Fixed(1)
11+
end
12+
end

+DSS_MATLAB/IActiveClass.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
% ActiveClassParent - Get the name of the parent class of the active class
1313
%
1414
% Methods:
15-
% ToJSON - Returns the data (as a list) of all elements from the active class as a JSON-encoded string. The `options` parameter contains bit-flags to toggle specific features. See `Obj_ToJSON` (C-API) for more. Additionally, the `ExcludeDisabled` flag can be used to excluded disabled elements from the output. (API Extension)
15+
% ToJSON - Returns the data (as a list) of all elements from the active class as a JSON-encoded string. The `options` parameter contains bit-flags to toggle specific features. See `Obj_ToJSON` (C-API) for more. Additionally, the `ExcludeDisabled` flag can be used to excluded disabled elements from the output. (API Extension)
1616

1717
properties
1818
ActiveClassName

+DSS_MATLAB/IBus.m

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,21 @@
1616
% Nodes - Integer Array of Node Numbers defined at the bus in same order as the voltages.
1717
% NumNodes - Number of Nodes this bus.
1818
% SectionID - Integer ID of the feeder section in which this bus is located.
19-
% SeqVoltages - Double Array of sequence voltages at this bus.
19+
% SeqVoltages - Double Array of sequence voltages at this bus. Magnitudes only.
2020
% TotalMiles - Total length of line downline from this bus, in miles. For recloser siting algorithm.
2121
% VLL - For 2- and 3-phase buses, returns array of complex numbers represetin L-L voltages in volts. Returns -1.0 for 1-phase bus. If more than 3 phases, returns only first 3.
22-
% VMagAngle - Array of doubles containing voltages in Magnitude (VLN), angle (deg)
22+
% VMagAngle - Array of doubles containing voltages in Magnitude (VLN), angle (degrees)
2323
% Voc - Open circuit voltage; Complex array.
2424
% Voltages - Complex array of voltages at this bus.
2525
% YscMatrix - Complex array of Ysc matrix at bus. Column by column.
2626
% Zsc0 - Complex Zero-Sequence short circuit impedance at bus.
27-
% Zsc1 - Complex Positive-Sequence short circuit impedance at bus..
27+
% Zsc1 - Complex Positive-Sequence short circuit impedance at bus.
2828
% ZscMatrix - Complex array of Zsc matrix at bus. Column by column.
2929
% kVBase - Base voltage at bus in kV
3030
% puVLL - Returns Complex array of pu L-L voltages for 2- and 3-phase buses. Returns -1.0 for 1-phase bus. If more than 3 phases, returns only 3 phases.
31-
% puVmagAngle - Array of doubles containig voltage magnitude, angle pairs in per unit
31+
% puVmagAngle - Array of doubles containing voltage magnitude, angle (degrees) pairs in per unit
3232
% puVoltages - Complex Array of pu voltages at the bus.
33+
% ZSC012Matrix - Array of doubles (complex) containing the complete 012 Zsc matrix. Only available after Zsc is computed, either through the "ZscRefresh" command, or running a "FaultStudy" solution. Only available for buses with 3 nodes.
3334
% x - X Coordinate for bus (double)
3435
% y - Y coordinate for bus(double)
3536
% LoadList - List of strings: Full Names of LOAD elements connected to the active bus.
@@ -70,6 +71,7 @@
7071
puVLL
7172
puVmagAngle
7273
puVoltages
74+
ZSC012Matrix
7375
x
7476
y
7577
LoadList
@@ -106,7 +108,7 @@
106108
% (read-only) Complex Double array of Sequence Voltages (0, 1, 2) at this Bus.
107109
calllib(obj.libname, 'ctx_Bus_Get_CplxSeqVoltages_GR', obj.dssctx);
108110
obj.CheckForError();
109-
result = obj.apiutil.get_float64_gr_array();
111+
result = obj.apiutil.get_complex128_gr_array();
110112
end
111113

112114
function result = get.Cust_Duration(obj)
@@ -137,7 +139,7 @@
137139
% (read-only) Short circuit currents at bus; Complex Array.
138140
calllib(obj.libname, 'ctx_Bus_Get_Isc_GR', obj.dssctx);
139141
obj.CheckForError();
140-
result = obj.apiutil.get_float64_gr_array();
142+
result = obj.apiutil.get_complex128_gr_array();
141143
end
142144

143145
function result = get.Lambda(obj)
@@ -184,7 +186,7 @@
184186
end
185187

186188
function result = get.SeqVoltages(obj)
187-
% (read-only) Double Array of sequence voltages at this bus.
189+
% (read-only) Double Array of sequence voltages at this bus. Magnitudes only.
188190
calllib(obj.libname, 'ctx_Bus_Get_SeqVoltages_GR', obj.dssctx);
189191
obj.CheckForError();
190192
result = obj.apiutil.get_float64_gr_array();
@@ -200,11 +202,11 @@
200202
% (read-only) For 2- and 3-phase buses, returns array of complex numbers represetin L-L voltages in volts. Returns -1.0 for 1-phase bus. If more than 3 phases, returns only first 3.
201203
calllib(obj.libname, 'ctx_Bus_Get_VLL_GR', obj.dssctx);
202204
obj.CheckForError();
203-
result = obj.apiutil.get_float64_gr_array();
205+
result = obj.apiutil.get_complex128_gr_array();
204206
end
205207

206208
function result = get.VMagAngle(obj)
207-
% (read-only) Array of doubles containing voltages in Magnitude (VLN), angle (deg)
209+
% (read-only) Array of doubles containing voltages in Magnitude (VLN), angle (degrees)
208210
calllib(obj.libname, 'ctx_Bus_Get_VMagAngle_GR', obj.dssctx);
209211
obj.CheckForError();
210212
result = obj.apiutil.get_float64_gr_array();
@@ -214,42 +216,42 @@
214216
% (read-only) Open circuit voltage; Complex array.
215217
calllib(obj.libname, 'ctx_Bus_Get_Voc_GR', obj.dssctx);
216218
obj.CheckForError();
217-
result = obj.apiutil.get_float64_gr_array();
219+
result = obj.apiutil.get_complex128_gr_array();
218220
end
219221

220222
function result = get.Voltages(obj)
221223
% (read-only) Complex array of voltages at this bus.
222224
calllib(obj.libname, 'ctx_Bus_Get_Voltages_GR', obj.dssctx);
223225
obj.CheckForError();
224-
result = obj.apiutil.get_float64_gr_array();
226+
result = obj.apiutil.get_complex128_gr_array();
225227
end
226228

227229
function result = get.YscMatrix(obj)
228230
% (read-only) Complex array of Ysc matrix at bus. Column by column.
229231
calllib(obj.libname, 'ctx_Bus_Get_YscMatrix_GR', obj.dssctx);
230232
obj.CheckForError();
231-
result = obj.apiutil.get_float64_gr_array();
233+
result = obj.apiutil.get_complex128_gr_array();
232234
end
233235

234236
function result = get.Zsc0(obj)
235237
% (read-only) Complex Zero-Sequence short circuit impedance at bus.
236238
calllib(obj.libname, 'ctx_Bus_Get_Zsc0_GR', obj.dssctx);
237239
obj.CheckForError();
238-
result = obj.apiutil.get_float64_gr_array();
240+
result = obj.apiutil.get_complex128_gr_simple();
239241
end
240242

241243
function result = get.Zsc1(obj)
242-
% (read-only) Complex Positive-Sequence short circuit impedance at bus..
244+
% (read-only) Complex Positive-Sequence short circuit impedance at bus.
243245
calllib(obj.libname, 'ctx_Bus_Get_Zsc1_GR', obj.dssctx);
244246
obj.CheckForError();
245-
result = obj.apiutil.get_float64_gr_array();
247+
result = obj.apiutil.get_complex128_gr_simple();
246248
end
247249

248250
function result = get.ZscMatrix(obj)
249251
% (read-only) Complex array of Zsc matrix at bus. Column by column.
250252
calllib(obj.libname, 'ctx_Bus_Get_ZscMatrix_GR', obj.dssctx);
251253
obj.CheckForError();
252-
result = obj.apiutil.get_float64_gr_array();
254+
result = obj.apiutil.get_complex128_gr_array();
253255
end
254256

255257
function result = get.kVBase(obj)
@@ -262,11 +264,11 @@
262264
% (read-only) Returns Complex array of pu L-L voltages for 2- and 3-phase buses. Returns -1.0 for 1-phase bus. If more than 3 phases, returns only 3 phases.
263265
calllib(obj.libname, 'ctx_Bus_Get_puVLL_GR', obj.dssctx);
264266
obj.CheckForError();
265-
result = obj.apiutil.get_float64_gr_array();
267+
result = obj.apiutil.get_complex128_gr_array();
266268
end
267269

268270
function result = get.puVmagAngle(obj)
269-
% (read-only) Array of doubles containig voltage magnitude, angle pairs in per unit
271+
% (read-only) Array of doubles containing voltage magnitude, angle (degrees) pairs in per unit
270272
calllib(obj.libname, 'ctx_Bus_Get_puVmagAngle_GR', obj.dssctx);
271273
obj.CheckForError();
272274
result = obj.apiutil.get_float64_gr_array();
@@ -276,7 +278,16 @@
276278
% (read-only) Complex Array of pu voltages at the bus.
277279
calllib(obj.libname, 'ctx_Bus_Get_puVoltages_GR', obj.dssctx);
278280
obj.CheckForError();
279-
result = obj.apiutil.get_float64_gr_array();
281+
result = obj.apiutil.get_complex128_gr_array();
282+
end
283+
284+
function result = get.ZSC012Matrix(obj)
285+
% Array of doubles (complex) containing the complete 012 Zsc matrix.
286+
% Only available after Zsc is computed, either through the "ZscRefresh" command, or running a "FaultStudy" solution.
287+
% Only available for buses with 3 nodes.
288+
calllib(obj.libname, 'ctx_Bus_Get_ZSC012Matrix_GR', obj.dssctx);
289+
obj.CheckForError();
290+
result = obj.apiutil.get_complex128_gr_array();
280291
end
281292

282293
function result = get.x(obj)

0 commit comments

Comments
 (0)