00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include <SuperLU.h>
00036 #include <SparseGenColLinSOE.h>
00037 #include <f2c.h>
00038 #include <math.h>
00039 #include <Channel.h>
00040 #include <FEM_ObjectBroker.h>
00041
00042
00043 SuperLU::SuperLU(int perm,
00044 double drop_tolerance,
00045 int panel,
00046 int relx,
00047 char symm)
00048 :SparseGenColLinSolver(SOLVER_TAGS_SuperLU),
00049 perm_r(0),perm_c(0), etree(0), sizePerm(0),
00050 relax(relx), permSpec(perm), panelSize(panel),
00051 drop_tol(drop_tolerance), symmetric(symm)
00052 {
00053
00054 options.Fact = DOFACT;
00055 options.Equil = YES;
00056 options.ColPerm = COLAMD;
00057 options.DiagPivotThresh = 1.0;
00058 options.Trans = NOTRANS;
00059 options.IterRefine = NOREFINE;
00060 options.SymmetricMode = NO;
00061 options.PivotGrowth = NO;
00062 options.ConditionNumber = NO;
00063 options.PrintStat = YES;
00064
00065 if (symmetric == 'Y')
00066 options.SymmetricMode = YES;
00067 L.ncol = 0;
00068 U.ncol = 0;
00069 A.ncol = 0;
00070 B.ncol = 0;
00071 }
00072
00073
00074 SuperLU::~SuperLU()
00075 {
00076
00077 if (perm_r != 0)
00078 delete [] perm_r;
00079 if (perm_c != 0)
00080 delete [] perm_c;
00081 if (etree != 0) {
00082 delete [] etree;
00083 StatFree(&stat);
00084 }
00085
00086 if (L.ncol != 0)
00087 Destroy_SuperNode_Matrix(&L);
00088 if (U.ncol != 0)
00089 Destroy_CompCol_Matrix(&U);
00090 if (AC.ncol != 0) {
00091 NCPformat *ACstore = (NCPformat *)AC.Store;
00092 SUPERLU_FREE(ACstore->colbeg);
00093 SUPERLU_FREE(ACstore->colend);
00094 SUPERLU_FREE(ACstore);
00095 }
00096 if (A.ncol != 0) {
00097 SUPERLU_FREE(A.Store);
00098 }
00099 if (B.ncol != 0) {
00100 SUPERLU_FREE(B.Store);
00101 }
00102 }
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130 int
00131 SuperLU::solve(void)
00132 {
00133 if (theSOE == 0) {
00134 opserr << "WARNING SuperLU::solve(void)- ";
00135 opserr << " No LinearSOE object has been set\n";
00136 return -1;
00137 }
00138
00139 int n = theSOE->size;
00140
00141
00142 if (n == 0)
00143 return 0;
00144
00145 if (sizePerm == 0) {
00146 opserr << "WARNING SuperLU::solve(void)- ";
00147 opserr << " size for row and col permutations 0 - has setSize() been called?\n";
00148 return -1;
00149 }
00150
00151
00152 double *Xptr = theSOE->X;
00153 double *Bptr = theSOE->B;
00154 for (int i=0; i<n; i++)
00155 *(Xptr++) = *(Bptr++);
00156
00157 if (theSOE->factored == false) {
00158
00159 int info;
00160
00161 if (L.ncol != 0 && symmetric == 'N') {
00162 Destroy_SuperNode_Matrix(&L);
00163 Destroy_CompCol_Matrix(&U);
00164 }
00165
00166 dgstrf(&options, &AC, drop_tol, relax, panelSize,
00167 etree, NULL, 0, perm_c, perm_r, &L, &U, &stat, &info);
00168
00169
00170 if (info != 0) {
00171 opserr << "WARNING SuperLU::solve(void)- ";
00172 opserr << " Error " << info << " returned in factorization dgstrf()\n";
00173 return -info;
00174 }
00175
00176 if (symmetric == 'Y')
00177 options.Fact= SamePattern_SameRowPerm;
00178 else
00179 options.Fact = SamePattern;
00180
00181 theSOE->factored = true;
00182 }
00183
00184
00185 trans_t trans = NOTRANS;
00186 int info;
00187 dgstrs (trans, &L, &U, perm_c, perm_r, &B, &stat, &info);
00188
00189 if (info != 0) {
00190 opserr << "WARNING SuperLU::solve(void)- ";
00191 opserr << " Error " << info << " returned in substitution dgstrs()\n";
00192 return -info;
00193 }
00194
00195 return 0;
00196 }
00197
00198
00199
00200
00201 int
00202 SuperLU::setSize()
00203 {
00204 int n = theSOE->size;
00205 if (n > 0) {
00206
00207
00208
00209 if (sizePerm < n) {
00210
00211 if (perm_r != 0)
00212 delete [] perm_r;
00213 perm_r = new int[n];
00214
00215 if (perm_c != 0)
00216 delete [] perm_c;
00217 perm_c = new int[n];
00218
00219 if (etree != 0)
00220 delete [] etree;
00221 etree = new int[n];
00222
00223 if (perm_r == 0 || perm_c == 0 || etree == 0) {
00224 opserr << "WARNING SuperLU::setSize()";
00225 opserr << " - ran out of memory\n";
00226 sizePerm = 0;
00227 return -1;
00228 }
00229 sizePerm = n;
00230 }
00231
00232
00233 StatInit(&stat);
00234
00235
00236 dCreate_CompCol_Matrix(&A, n, n, theSOE->nnz, theSOE->A,
00237 theSOE->rowA, theSOE->colStartA,
00238 SLU_NC, SLU_D, SLU_GE);
00239
00240
00241 get_perm_c(permSpec, &A, perm_c);
00242
00243 sp_preorder(&options, &A, perm_c, etree, &AC);
00244
00245
00246 dCreate_Dense_Matrix(&B, n, 1, theSOE->X, n, SLU_DN, SLU_D, SLU_GE);
00247
00248
00249
00250 options.Fact = DOFACT;
00251
00252 if (symmetric == 'Y')
00253 options.SymmetricMode=YES;
00254
00255 } else if (n == 0)
00256 return 0;
00257 else {
00258 opserr << "WARNING SuperLU::setSize()";
00259 opserr << " - order of system < 0\n";
00260 return -1;
00261 }
00262
00263 return 0;
00264 }
00265
00266 int
00267 SuperLU::sendSelf(int cTag, Channel &theChannel)
00268 {
00269
00270 return 0;
00271 }
00272
00273 int
00274 SuperLU::recvSelf(int ctag,
00275 Channel &theChannel,
00276 FEM_ObjectBroker &theBroker)
00277 {
00278
00279 return 0;
00280 }
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295