00001 #include "AdmittanceNetwork_SUPERLU.h"
00002 #include <iostream>
00003 using namespace std;
00004
00005 AdmittanceNetwork_SUPERLU::AdmittanceNetwork_SUPERLU(int N, bool init_eye):
00006 N(N),
00007 Nalloc(N)
00008 {
00009
00010 if ( !(perm_r = intMalloc(N)) ) ABORT("Malloc failed for perm_r[]");
00011 if ( !(perm_c = intMalloc(N)) ) ABORT("Malloc failed for perm_c[]");
00012
00013
00014 dirty_val = dirty_struct = true;
00015
00016 if ( !(rhs = doublecomplexMalloc(N)) ) ABORT("Malloc failed for rhs[]");
00017 zCreate_Dense_Matrix(&B,N,1,rhs,N,SLU_DN,SLU_Z,SLU_GE);
00018
00019 doublecomplex *a;
00020 int *arow, *acol;
00021 if ( !(a = doublecomplexMalloc(N)) ) ABORT("Malloc failed for a[]");
00022 if ( !(arow = intMalloc(N)) ) ABORT("Malloc failed for arow[]");
00023 if ( !(acol = intMalloc(N+1)) ) ABORT("Malloc failed for acol[]");
00024 for (int i = 0; i < N; i++)
00025 {
00026
00027 a[i].r = 1.0*init_eye; a[i].i = 0.0;
00028 arow[i] = acol[i] = i;
00029 }
00030 acol[N] = N;
00031 zCreate_CompCol_Matrix(&A,N,N,N,a,arow,acol,SLU_NC,SLU_Z,SLU_GE);
00032
00033 L.Store = U.Store = NULL;
00034
00035 set_default_options(&options);
00036 }
00037
00038 AdmittanceNetwork_SUPERLU::~AdmittanceNetwork_SUPERLU()
00039 {
00040 SUPERLU_FREE(rhs);
00041 SUPERLU_FREE(perm_r);
00042 SUPERLU_FREE(perm_c);
00043 Destroy_CompCol_Matrix(&A);
00044 Destroy_SuperMatrix_Store(&B);
00045 if (L.Store != NULL)
00046 {
00047 Destroy_SuperNode_Matrix(&L);
00048 Destroy_CompCol_Matrix(&U);
00049 }
00050 }
00051
00052 void AdmittanceNetwork_SUPERLU::set(int i, int j, Complex z)
00053 {
00054
00055 NCformat *Astore = (NCformat*)(A.Store);
00056 doublecomplex *data = (doublecomplex*)(Astore->nzval);
00057
00058 const int col_end = Astore->colptr[j+1];
00059 for (int col = Astore->colptr[j]; col < col_end; col++)
00060 {
00061
00062 if (Astore->rowind[col] == i)
00063 {
00064
00065 bool new_dirty_val = (data[col].r != real(z) ||
00066 data[col].i != imag(z));
00067 if (!new_dirty_val) return;
00068 dirty_val = true;
00069
00070 data[col].r = real(z);
00071 data[col].i = imag(z);
00072
00073 if (data[col].i == 0.0 && data[col].r == 0.0)
00074 {
00075
00076 for (int p = col+1; p < Astore->nnz; p++)
00077 {
00078 data[p-1].r = data[p].r;
00079 data[p-1].i = data[p].i;
00080 Astore->rowind[p-1] = Astore->rowind[p];
00081 }
00082
00083
00084 for (int p = j+1; p < N; p++)
00085 {
00086 Astore->colptr[p]--;
00087 }
00088
00089 Astore->colptr[N] = --(Astore->nnz);
00090
00091 dirty_struct = true;
00092 }
00093 return;
00094 }
00095 }
00096
00097
00098 if (real(z) == 0.0 && imag(z) == 0.0) return;
00099
00100 Astore->colptr[N] = ++(Astore->nnz);
00101
00102 dirty_val = dirty_struct = true;
00103
00104 if (Astore->nnz >= Nalloc)
00105 {
00106 Nalloc += 1;
00107 Astore->rowind =
00108 (int*)realloc(Astore->rowind,Nalloc*sizeof(int));
00109 Astore->nzval = realloc(Astore->nzval,
00110 Nalloc*sizeof(doublecomplex));
00111 data = (doublecomplex*)(Astore->nzval);
00112 }
00113
00114 for (int p = Astore->nnz-1; p > col_end; p--)
00115 {
00116 Astore->rowind[p] = Astore->rowind[p-1];
00117 data[p] = data[p-1];
00118 }
00119
00120 data[col_end].r = real(z);
00121 data[col_end].i = imag(z);
00122 Astore->rowind[col_end] = i;
00123
00124 for (int p = j+1; p < N; p++) Astore->colptr[p]++;
00125 }
00126
00127 Complex AdmittanceNetwork_SUPERLU::get(int i, int j) const
00128 {
00129 Complex result(0.0,0.0);
00130 NCformat* Astore = (NCformat*)(A.Store);
00131 doublecomplex *data = (doublecomplex*)(Astore->nzval);
00132 int col = Astore->colptr[j];
00133 int col_end = Astore->colptr[j+1];
00134 for (; col < col_end; col++)
00135 {
00136 if (Astore->rowind[col] == i)
00137 {
00138 result = Complex(data[col].r,data[col].i);
00139 break;
00140 }
00141 }
00142 return result;
00143 }
00144
00145 void AdmittanceNetwork_SUPERLU::add_line(int i, int j, Complex y, double turns, double phase_shift, int side)
00146 {
00147 Complex a = polar(turns,phase_shift);
00148 set(side,side,get(side,side)+a*a*y);
00149 int off_side = i;
00150 if (side == off_side) off_side = j;
00151 set(off_side,off_side,get(off_side,off_side)+y);
00152 Complex tmp = get(i,j)-a*y;
00153 set(i,j,tmp);
00154 set(j,i,tmp);
00155 }
00156
00157 void AdmittanceNetwork_SUPERLU::remove_line(int i, int j, Complex y, double turns, double phase_shift, int side)
00158 {
00159 Complex a = polar(turns,phase_shift);
00160 set(side,side,get(side,side)-a*a*y);
00161 int off_side = i;
00162 if (side == off_side) off_side = j;
00163 set(off_side,off_side,get(off_side,off_side)-y);
00164 Complex tmp = get(i,j)+a*y;
00165 set(i,j,tmp);
00166 set(j,i,tmp);
00167 }
00168
00169 void AdmittanceNetwork_SUPERLU::add_line(int i, int j, Complex y)
00170 {
00171 set(i,i,get(i,i)+y);
00172 set(j,j,get(j,j)+y);
00173
00174
00175 Complex tmp = get(i,j)-y;
00176 set(i,j,tmp);
00177 set(j,i,tmp);
00178 }
00179
00180 void AdmittanceNetwork_SUPERLU::remove_line(int i, int j, Complex y)
00181 {
00182 add_line(i,j,-y);
00183 }
00184
00185 void AdmittanceNetwork_SUPERLU::add_self(int i, Complex y)
00186 {
00187 set(i,i,get(i,i)+y);
00188 }
00189
00190 void AdmittanceNetwork_SUPERLU::remove_self(int i, Complex y)
00191 {
00192 add_self(i,-y);
00193 }
00194
00195 void AdmittanceNetwork_SUPERLU::solve_for_voltage(const Complex* I, Complex* V)
00196 {
00197
00198 for (int i = 0; i < N; i++)
00199 {
00200 rhs[i].r = real(I[i]);
00201 rhs[i].i = imag(I[i]);
00202 }
00203
00204 int info;
00205 SuperLUStat_t stat;
00206 StatInit(&stat);
00207
00208 if (dirty_struct || dirty_val)
00209 {
00210 options.Fact = DOFACT;
00211 if (U.Store != NULL)
00212 {
00213 Destroy_CompCol_Matrix(&U);
00214 Destroy_SuperNode_Matrix(&L);
00215 }
00216 zgssv(&options,&A,perm_c,perm_r,&L,&U,&B,&stat,&info);
00217 }
00218
00219 else
00220 {
00221 options.Fact = FACTORED;
00222 zgstrs(NOTRANS,&L,&U,perm_c,perm_r,&B,&stat,&info);
00223 }
00224 StatFree(&stat);
00225 dirty_val = dirty_struct = false;
00226
00227 for (int i = 0; i < N; i++)
00228 {
00229 V[i] = Complex(rhs[i].r,rhs[i].i);
00230 }
00231 }
00232
00233 void AdmittanceNetwork_SUPERLU::solve_for_current(const Complex* V, Complex* I)
00234 {
00235
00236 for (int p = 0; p < N; p++)
00237 {
00238 I[p] = Complex(0.0,0.0);
00239 }
00240
00241 NCformat *Astore = (NCformat*)(A.Store);
00242 doublecomplex *data = (doublecomplex*)(Astore->nzval);
00243
00244 int col = 0;
00245 for (int p = 0; p < Astore->nnz; p++)
00246 {
00247
00248 if (Astore->colptr[col+1] == p) col++;
00249
00250 Complex a(data[p].r,data[p].i);
00251 I[Astore->rowind[p]] += a*V[col];
00252 }
00253 }
00254