Skip to content

Commit

Permalink
API: Implement optional matrix sizes
Browse files Browse the repository at this point in the history
Reminder: the docs still need to be updated to reflect the change.

Closes #113
  • Loading branch information
PMeira committed Mar 23, 2023
1 parent 03ed2cf commit 8c2eab9
Show file tree
Hide file tree
Showing 18 changed files with 249 additions and 119 deletions.
37 changes: 32 additions & 5 deletions include/dss_capi.h
Original file line number Diff line number Diff line change
Expand Up @@ -563,7 +563,9 @@ extern "C" {
DSS_CAPI_DLL void Bus_Get_LoadList_GR(void);

/*!
Array of 18 doubles (9 complex values) containing the complete 012 Zsc matrix
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.
*/
DSS_CAPI_DLL void Bus_Get_ZSC012Matrix(double** ResultPtr, int32_t* ResultCount);
/*!
Expand Down Expand Up @@ -1197,7 +1199,7 @@ extern "C" {
DSS_CAPI_DLL void CktElement_Get_Powers_GR(void);

/*!
Double array of symmetrical component currents into each 3-phase terminal
Double array of symmetrical component currents (magnitudes only) into each 3-phase terminal
*/
DSS_CAPI_DLL void CktElement_Get_SeqCurrents(double** ResultPtr, int32_t* ResultCount);
/*!
Expand All @@ -1206,7 +1208,7 @@ extern "C" {
DSS_CAPI_DLL void CktElement_Get_SeqCurrents_GR(void);

/*!
Double array of sequence powers into each 3-phase teminal
Complex array of sequence powers (kW, kvar) into each 3-phase teminal
*/
DSS_CAPI_DLL void CktElement_Get_SeqPowers(double** ResultPtr, int32_t* ResultCount);
/*!
Expand All @@ -1215,7 +1217,7 @@ extern "C" {
DSS_CAPI_DLL void CktElement_Get_SeqPowers_GR(void);

/*!
Double array of symmetrical component voltages at each 3-phase terminal
Double array of symmetrical component voltages (magnitudes only) at each 3-phase terminal
*/
DSS_CAPI_DLL void CktElement_Get_SeqVoltages(double** ResultPtr, int32_t* ResultCount);
/*!
Expand Down Expand Up @@ -1259,7 +1261,7 @@ extern "C" {
DSS_CAPI_DLL int32_t CktElement_Get_NumProperties(void);

/*!
Residual currents for each terminal: (mag, angle)
Residual currents for each terminal: (magnitude, angle in degrees)
*/
DSS_CAPI_DLL void CktElement_Get_Residuals(double** ResultPtr, int32_t* ResultCount);
/*!
Expand Down Expand Up @@ -1691,6 +1693,28 @@ extern "C" {
*/
DSS_CAPI_DLL uint16_t DSS_Get_AllowChangeDir(void);
DSS_CAPI_DLL void DSS_Set_AllowChangeDir(uint16_t Value);

/*!
If enabled, the engine will fill the array dimensions as the third and forth elements of
the "count" pointer (first elements is the current size, second is the capacity). For user-managed
memory, the user must provide a valid "count" pointer with the correct capacity.
Most matrices from the DSS engine are column-major (a.k.a. "Fortran order").
If the array is not a matrix, the elements are left as zeroes, i.e. the current size can be used as
the dimension of the vector.
For complex matrices, the sizes are referred to the number of complex elements, not the primary the float64 elements.
Defaults to False/0 in the 0.13.x versions of DSS C-API.
This might change to false in future versions.
This can also be set through the environment variable DSS_CAPI_ARRAY_DIMS. Setting it to 1 to
enable the behavior on start-up.
(API Extension)
*/
DSS_CAPI_DLL uint16_t DSS_Get_EnableArrayDimensions(void);
DSS_CAPI_DLL void DSS_Set_EnableArrayDimensions(uint16_t Value);

/*!
If enabled, in case of errors or empty arrays, the API returns arrays with values compatible with the
Expand Down Expand Up @@ -2676,6 +2700,9 @@ extern "C" {
*/
DSS_CAPI_DLL double Lines_Get_X0(void);

/*!
Reactance matrix (full), ohms per unit length. Array of doubles.
*/
DSS_CAPI_DLL void Lines_Get_Xmatrix(double** ResultPtr, int32_t* ResultCount);
/*!
Same as Lines_Get_Xmatrix but using the global buffer interface for results
Expand Down
37 changes: 32 additions & 5 deletions include/dss_capi_ctx.h
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,9 @@ extern "C" {
DSS_CAPI_DLL void ctx_Bus_Get_LoadList_GR(void* ctx);

/*!
Array of 18 doubles (9 complex values) containing the complete 012 Zsc matrix
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.
*/
DSS_CAPI_DLL void ctx_Bus_Get_ZSC012Matrix(void* ctx, double** ResultPtr, int32_t* ResultCount);
/*!
Expand Down Expand Up @@ -1025,7 +1027,7 @@ extern "C" {
DSS_CAPI_DLL void ctx_CktElement_Get_Powers_GR(void* ctx);

/*!
Double array of symmetrical component currents into each 3-phase terminal
Double array of symmetrical component currents (magnitudes only) into each 3-phase terminal
*/
DSS_CAPI_DLL void ctx_CktElement_Get_SeqCurrents(void* ctx, double** ResultPtr, int32_t* ResultCount);
/*!
Expand All @@ -1034,7 +1036,7 @@ extern "C" {
DSS_CAPI_DLL void ctx_CktElement_Get_SeqCurrents_GR(void* ctx);

/*!
Double array of sequence powers into each 3-phase teminal
Complex array of sequence powers (kW, kvar) into each 3-phase teminal
*/
DSS_CAPI_DLL void ctx_CktElement_Get_SeqPowers(void* ctx, double** ResultPtr, int32_t* ResultCount);
/*!
Expand All @@ -1043,7 +1045,7 @@ extern "C" {
DSS_CAPI_DLL void ctx_CktElement_Get_SeqPowers_GR(void* ctx);

/*!
Double array of symmetrical component voltages at each 3-phase terminal
Double array of symmetrical component voltages (magnitudes only) at each 3-phase terminal
*/
DSS_CAPI_DLL void ctx_CktElement_Get_SeqVoltages(void* ctx, double** ResultPtr, int32_t* ResultCount);
/*!
Expand Down Expand Up @@ -1087,7 +1089,7 @@ extern "C" {
DSS_CAPI_DLL int32_t ctx_CktElement_Get_NumProperties(void* ctx);

/*!
Residual currents for each terminal: (mag, angle)
Residual currents for each terminal: (magnitude, angle in degrees)
*/
DSS_CAPI_DLL void ctx_CktElement_Get_Residuals(void* ctx, double** ResultPtr, int32_t* ResultCount);
/*!
Expand Down Expand Up @@ -1519,6 +1521,28 @@ extern "C" {
*/
DSS_CAPI_DLL uint16_t ctx_DSS_Get_AllowChangeDir(void* ctx);
DSS_CAPI_DLL void ctx_DSS_Set_AllowChangeDir(void* ctx, uint16_t Value);

/*!
If enabled, the engine will fill the array dimensions as the third and forth elements of
the "count" pointer (first elements is the current size, second is the capacity). For user-managed
memory, the user must provide a valid "count" pointer with the correct capacity.
Most matrices from the DSS engine are column-major (a.k.a. "Fortran order").
If the array is not a matrix, the elements are left as zeroes, i.e. the current size can be used as
the dimension of the vector.
For complex matrices, the sizes are referred to the number of complex elements, not the primary the float64 elements.
Defaults to False/0 in the 0.13.x versions of DSS C-API.
This might change to false in future versions.
This can also be set through the environment variable DSS_CAPI_ARRAY_DIMS. Setting it to 1 to
enable the behavior on start-up.
(API Extension)
*/
DSS_CAPI_DLL uint16_t ctx_DSS_Get_EnableArrayDimensions(void* ctx);
DSS_CAPI_DLL void ctx_DSS_Set_EnableArrayDimensions(void* ctx, uint16_t Value);

/*!
If enabled, in case of errors or empty arrays, the API returns arrays with values compatible with the
Expand Down Expand Up @@ -2504,6 +2528,9 @@ extern "C" {
*/
DSS_CAPI_DLL double ctx_Lines_Get_X0(void* ctx);

/*!
Reactance matrix (full), ohms per unit length. Array of doubles.
*/
DSS_CAPI_DLL void ctx_Lines_Get_Xmatrix(void* ctx, double** ResultPtr, int32_t* ResultCount);
/*!
Same as Lines_Get_Xmatrix but using the global buffer interface for results
Expand Down
6 changes: 3 additions & 3 deletions src/CAPI/CAPI_Bus.pas
Original file line number Diff line number Diff line change
Expand Up @@ -495,7 +495,7 @@ procedure Bus_Get_ZscMatrix(var ResultPtr: PDouble; ResultCount: PAPISize); CDEC
if Assigned(Buses^[ActiveBusIndex].Zsc) then
begin
Nelements := Buses^[ActiveBusIndex].Zsc.Order;
Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, 2 * Nelements * Nelements);
Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, 2 * Nelements * Nelements, Nelements, Nelements);
iV := 0;
with Buses^[ActiveBusIndex] do
for i := 1 to Nelements do
Expand Down Expand Up @@ -548,7 +548,7 @@ procedure Bus_Get_YscMatrix(var ResultPtr: PDouble; ResultCount: PAPISize); CDEC
if Assigned(Buses^[ActiveBusIndex].Ysc) then
begin
Nelements := Buses^[ActiveBusIndex].Ysc.Order;
Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, 2 * Nelements * Nelements);
Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, 2 * Nelements * Nelements, Nelements, Nelements);
iV := 0;
with Buses^[ActiveBusIndex] do
for i := 1 to Nelements do
Expand Down Expand Up @@ -1246,7 +1246,7 @@ procedure Bus_Get_ZSC012Matrix(var ResultPtr: PDouble; ResultCount: PAPISize); C
Zsc012Temp.Free;

// Return all the elements of ZSC012
DSS_RecreateArray_PDouble(ResultPtr, ResultCount, NValues);
DSS_RecreateArray_PDouble(ResultPtr, ResultCount, NValues, NumNodesThisBus, NumNodesThisBus);
Move(ZSC012.GetValuesArrayPtr(Norder)[1], ResultPtr[0], NValues * SizeOf(Double));
end;
end;
Expand Down
2 changes: 1 addition & 1 deletion src/CAPI/CAPI_Circuit.pas
Original file line number Diff line number Diff line change
Expand Up @@ -652,7 +652,7 @@ procedure Circuit_Get_SystemY(var ResultPtr: PDouble; ResultCount: PAPISize); CD
GetCompressedMatrix(hY, nBus + 1, nNZ, @ColPtr[0], @RowIdx[0], @cVals[0]);

// allocate a square matrix
Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, 2 * NumNodes * NumNodes); // Make array for complex
Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, 2 * NumNodes * NumNodes, NumNodes, NumNodes); // Make array for complex

// DSS_RecreateArray_PDouble already zero-fills the array

Expand Down
38 changes: 18 additions & 20 deletions src/CAPI/CAPI_CktElement.pas
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,7 @@ procedure CktElement_Get_Currents(var ResultPtr: PDouble; ResultCount: PAPISize)

with DSSPrime.ActiveCircuit.ActiveCktElement do
begin
Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, 2 * (NConds * NTerms));
Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, 2 * (NConds * NTerms), NConds, NTerms);
GetCurrents(pComplexArray(Result));
end
end;
Expand All @@ -388,7 +388,7 @@ procedure CktElement_Get_Voltages(var ResultPtr: PDouble; ResultCount: PAPISize)

with DSSPrime.ActiveCircuit, ActiveCktElement do
begin
Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, 2 * (NConds * Nterms));
Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, 2 * (NConds * Nterms), NConds, Nterms);
// k := (Terminal-1)*numcond; // RCD 8-30-00 Changed
iV := 0;
for i := 1 to NConds * Nterms do
Expand Down Expand Up @@ -553,7 +553,7 @@ procedure CktElement_Get_SeqCurrents(var ResultPtr: PDouble; ResultCount: PAPISi
with DSSPrime.ActiveCircuit, ActiveCktElement do
begin
try
Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, 3 * NTerms);
Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, 3 * NTerms, 3, NTerms);

i012 := Allocmem(sizeof(Complex) * 3 * Nterms);
// get complex seq voltages
Expand Down Expand Up @@ -605,7 +605,7 @@ procedure CktElement_Get_SeqPowers(var ResultPtr: PDouble; ResultCount: PAPISize

with DSSPrime.ActiveCircuit, ActiveCktElement do
begin
Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, 2 * 3 * NTerms); // allocate for kW and kvar
Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, 2 * 3 * NTerms, 3, NTerms); // allocate for kW and kvar
if NPhases <> 3 then
begin
if (Nphases = 1) and PositiveSequence then
Expand All @@ -614,7 +614,7 @@ procedure CktElement_Get_SeqPowers(var ResultPtr: PDouble; ResultCount: PAPISize
cBuffer := Allocmem(sizeof(Complex) * NValues);
GetCurrents(cBuffer);
iCount := 2; // Start with kW1
{Put only phase 1 quantities in Pos seq}
// Put only phase 1 quantities in Pos seq
for j := 1 to NTerms do
begin
k := (j - 1) * NConds;
Expand Down Expand Up @@ -652,7 +652,7 @@ procedure CktElement_Get_SeqPowers(var ResultPtr: PDouble; ResultCount: PAPISize
S := V012[i] * cong(I012[i]);
Result[icount] := S.re * 0.003; // 3-phase kW conversion
inc(icount);
Result[icount] := S.im * 0.003; // 3-phase kW conversion
Result[icount] := S.im * 0.003; // 3-phase kvar conversion
inc(icount);
end;
end;
Expand All @@ -670,7 +670,7 @@ procedure CktElement_Get_SeqPowers_GR(); CDECL;

//------------------------------------------------------------------------------
procedure CktElement_Get_SeqVoltages(var ResultPtr: PDouble; ResultCount: PAPISize); CDECL;
// All voltages of active ciruit element
// All voltages of active circuit element
// magnitude only
// returns a set of seq voltages (3) for each terminal
// 0, 1, 2 sequence (0, +, -)
Expand All @@ -692,7 +692,7 @@ procedure CktElement_Get_SeqVoltages(var ResultPtr: PDouble; ResultCount: PAPISi
with DSSPrime.ActiveCircuit, ActiveCktElement do
begin
try
Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, (3 * NTerms - 1) + 1);
Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, 3 * NTerms, 3, NTerms);

V012 := Allocmem(sizeof(Complex) * 3 * Nterms);
// get complex seq voltages
Expand Down Expand Up @@ -859,7 +859,7 @@ procedure CktElement_Get_Residuals(var ResultPtr: PDouble; ResultCount: PAPISize

with DSSPrime.ActiveCircuit.ActiveCktElement do
begin
Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, 2 * NTerms); // 2 values per terminal
Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, 2 * NTerms, 2, NTerms); // 2 values per terminal
cBuffer := Allocmem(sizeof(Complex) * Yorder);
GetCurrents(cBuffer);
iV := 0;
Expand Down Expand Up @@ -889,8 +889,6 @@ procedure CktElement_Get_Residuals_GR(); CDECL;

//------------------------------------------------------------------------------
procedure CktElement_Get_Yprim(var ResultPtr: PDouble; ResultCount: PAPISize); CDECL;
{ Return the YPrim matrix for this element }

var
cValues: pComplexArray;
begin
Expand All @@ -902,8 +900,10 @@ procedure CktElement_Get_Yprim(var ResultPtr: PDouble; ResultCount: PAPISize); C
with DSSPrime.ActiveCircuit.ActiveCktElement do
begin
cValues := GetYprimValues(ALL_YPRIM); // Get pointer to complex array of values
if cValues = NIL then Exit;
DSS_RecreateArray_PDouble(ResultPtr, ResultCount, 2 * Yorder * Yorder);
if cValues = NIL then
Exit;

DSS_RecreateArray_PDouble(ResultPtr, ResultCount, 2 * Yorder * Yorder, Yorder, Yorder);
Move(cValues^, ResultPtr^, ResultCount^ * SizeOf(Double));
end
end;
Expand Down Expand Up @@ -1045,7 +1045,6 @@ function CktElement_Get_HasSwitchControl(): TAPIBoolean; CDECL;
end;
//------------------------------------------------------------------------------
procedure CktElement_Get_CplxSeqVoltages(var ResultPtr: PDouble; ResultCount: PAPISize); CDECL;
{returns Seq Voltages as array of complex values}
var
S: String;
begin
Expand All @@ -1061,7 +1060,7 @@ procedure CktElement_Get_CplxSeqVoltages(var ResultPtr: PDouble; ResultCount: PA
with DSSPrime.ActiveCircuit, ActiveCktElement do
begin
try
DSS_RecreateArray_PDouble(ResultPtr, ResultCount, 2 * 3 * NTerms);
DSS_RecreateArray_PDouble(ResultPtr, ResultCount, 2 * 3 * NTerms, 3, NTerms);
CalcSeqVoltages(ActiveCktElement, pComplexArray(ResultPtr));

except
Expand All @@ -1086,7 +1085,6 @@ procedure CktElement_Get_CplxSeqVoltages_GR(); CDECL;

//------------------------------------------------------------------------------
procedure CktElement_Get_CplxSeqCurrents(var ResultPtr: PDouble; ResultCount: PAPISize); CDECL;
{returns Seq Voltages as array of complex values}
var
Result: PDoubleArray0;
i012: pComplexArray;
Expand All @@ -1101,7 +1099,7 @@ procedure CktElement_Get_CplxSeqCurrents(var ResultPtr: PDouble; ResultCount: PA
with DSSPrime.ActiveCircuit, ActiveCktElement do
begin
try
Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, 2 * 3 * NTerms);
Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, 2 * 3 * NTerms, 3, NTerms);
i012 := pComplexArray(Result);
// get complex seq voltages
_CalcSeqCurrents(ActiveCktElement, i012);
Expand Down Expand Up @@ -1279,7 +1277,7 @@ procedure CktElement_Get_NodeOrder(var ResultPtr: PInteger; ResultCount: PAPISiz
Exit;
end;

Result := DSS_RecreateArray_PInteger(ResultPtr, ResultCount, NTerms * Nconds);
Result := DSS_RecreateArray_PInteger(ResultPtr, ResultCount, NTerms * Nconds, Nconds, NTerms);
k := 0;
for i := 1 to Nterms do
begin
Expand Down Expand Up @@ -1375,7 +1373,7 @@ procedure CktElement_Get_CurrentsMagAng(var ResultPtr: PDouble; ResultCount: PAP
with DSSPrime.ActiveCircuit.ActiveCktElement do
begin
NValues := NConds * NTerms;
Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, 2 * NValues);
Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, 2 * NValues, 2, NValues);
cBuffer := PComplexArray(ResultPtr);
GetCurrents(cBuffer);
iV := 0;
Expand Down Expand Up @@ -1414,7 +1412,7 @@ procedure CktElement_Get_VoltagesMagAng(var ResultPtr: PDouble; ResultCount: PAP
with DSSPrime.ActiveCircuit, ActiveCktElement do
begin
numcond := NConds * Nterms;
Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, 2 * numcond);
Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, 2 * numcond, 2, numcond);
// k := (Terminal-1)*numcond; // RCD 8-30-00 Changed
iV := 0;
for i := 1 to numcond do
Expand Down
Loading

0 comments on commit 8c2eab9

Please sign in to comment.