00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "SymArpackSOE.h"
00013 #include "SymArpackSolver.h"
00014 #include <Matrix.h>
00015 #include <Graph.h>
00016 #include <Vertex.h>
00017 #include <VertexIter.h>
00018 #include <math.h>
00019 #include <Channel.h>
00020 #include <FEM_ObjectBroker.h>
00021 #include <AnalysisModel.h>
00022 #include <Vector.h>
00023
00024 SymArpackSOE::SymArpackSOE(SymArpackSolver &the_Solver, AnalysisModel &aModel,
00025 double theShift)
00026 :EigenSOE(the_Solver, EigenSOE_TAGS_SymArpackSOE),
00027 size(0), nnz(0), colA(0), rowStartA(0),
00028 factored(false), shift(theShift), theModel(&aModel),
00029 nblks(0), xblk(0), invp(0), diag(0), penv(0), rowblks(0),
00030 begblk(0), first(0)
00031 {
00032 the_Solver.setEigenSOE(*this);
00033 }
00034
00035
00036 SymArpackSOE::~SymArpackSOE()
00037 {
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 }
00054
00055
00056 int
00057 SymArpackSOE::getNumEqn(void) const
00058 {
00059 return size;
00060 }
00061
00062
00063 extern "C" int symFactorization(int *fxadj, int *adjncy, int neq, int LSPARSE,
00064 int **xblkMY, int **invpMY, int **rowblksMY,
00065 OFFDBLK ***begblkMY, OFFDBLK **firstMY,
00066 double ***penvMY, double **diagMY);
00067
00068 int
00069 SymArpackSOE::setSize(Graph &theGraph)
00070 {
00071 int result = 0;
00072 int oldSize = size;
00073 size = theGraph.getNumVertex();
00074
00075
00076 Vertex *theVertex;
00077 int newNNZ = 0;
00078 VertexIter &theVertices = theGraph.getVertices();
00079 while ((theVertex = theVertices()) != 0) {
00080 const ID &theAdjacency = theVertex->getAdjacency();
00081 newNNZ += theAdjacency.Size();
00082 }
00083 nnz = newNNZ;
00084
00085 if (colA != 0)
00086 delete [] colA;
00087
00088 colA = new int[newNNZ];
00089 if (colA == 0) {
00090 opserr << "WARNING SymArpackSOE::SymArpackSOE :";
00091 opserr << " ran out of memory for colA with nnz = ";
00092 opserr << newNNZ << " \n";
00093 size = 0; nnz = 0;
00094 result = -1;
00095 }
00096
00097 factored = false;
00098
00099 if (rowStartA != 0)
00100 delete [] rowStartA;
00101 rowStartA = new int[size+1];
00102 if (rowStartA == 0) {
00103 opserr << "SymArpackSOE::ran out of memory for rowStartA." << endln;
00104 result = -1;
00105 }
00106
00107
00108 if (size != 0) {
00109 rowStartA[0] = 0;
00110 int startLoc = 0;
00111 int lastLoc = 0;
00112
00113 for (int a=0; a<size; a++) {
00114 theVertex = theGraph.getVertexPtr(a);
00115 if (theVertex == 0) {
00116 opserr << "WARNING:SymArpackSOE::setSize :";
00117 opserr << " vertex " << a << " not in graph! - size set to 0\n";
00118 size = 0;
00119 return -1;
00120 }
00121
00122 const ID &theAdjacency = theVertex->getAdjacency();
00123 int idSize = theAdjacency.Size();
00124
00125
00126 for (int i=0; i<idSize; i++) {
00127 int row = theAdjacency(i);
00128 bool foundPlace = false;
00129
00130 for (int j=startLoc; j<lastLoc; j++)
00131 if (colA[j] > row) {
00132
00133
00134 for (int k=lastLoc; k>j; k--)
00135 colA[k] = colA[k-1];
00136 colA[j] = row;
00137 foundPlace = true;
00138 j = lastLoc;
00139 }
00140
00141 if (foundPlace == false)
00142 colA[lastLoc] = row;
00143
00144 lastLoc++;
00145 }
00146 rowStartA[a+1] = lastLoc;;
00147 startLoc = lastLoc;
00148 }
00149 }
00150
00151
00152
00153
00154 int LSPARSE = 1;
00155
00156
00157
00158
00159 nblks = symFactorization(rowStartA, colA, size, LSPARSE,
00160 &xblk, &invp, &rowblks, &begblk, &first, &penv, &diag);
00161
00162
00163 EigenSolver *theSolvr = this->getSolver();
00164 int solverOK = theSolvr->setSize();
00165 if (solverOK < 0) {
00166 opserr << "WARNING:BandArpackSOE::setSize :";
00167 opserr << " solver failed setSize()\n";
00168 return solverOK;
00169 }
00170
00171
00172 return result;
00173 }
00174
00175
00176 int
00177 SymArpackSOE::addA(const Matrix &m, const ID &id, double fact)
00178 {
00179
00180 if (fact == 0.0)
00181 return 0;
00182
00183 int idSize = id.Size();
00184
00185
00186 if (idSize != m.noRows() && idSize != m.noCols()) {
00187 opserr << "SymArpackSOE::addA() ";
00188 opserr << " - Matrix and ID not of similar sizes\n";
00189 return -1;
00190 }
00191
00192 int *newID = new int [idSize];
00193 int *isort = new int[idSize];
00194 if (newID == 0 || isort ==0) {
00195 opserr << "WARNING SymArpackSOE::addA() :";
00196 opserr << " ran out of memory for vectors (newID, isort)";
00197 return -1;
00198 }
00199
00200 int i;
00201 for (i=0; i<idSize; i++) {
00202 newID[i] = id(i);
00203 if (newID[i] >= 0)
00204 newID[i] = invp[newID[i]];
00205 }
00206
00207 long int i_eq, j_eq, iadd;
00208 int j, nee, lnee;
00209 int k, ipos, jpos;
00210 int it, jt;
00211 int iblk;
00212 int jblk;
00213 OFFDBLK *ptr;
00214 OFFDBLK *saveblk;
00215 double *fpt, *iloc, *loc;
00216
00217 nee = idSize;
00218 lnee = nee;
00219
00220
00221 for(i = 0, k = 0; i < lnee ; i++ )
00222 {
00223 if( newID[i] >= 0 ) {
00224 isort[k] = i;
00225 k++;
00226 }
00227 }
00228
00229 lnee = k;
00230
00231 i = k - 1;
00232 do
00233 {
00234 k = 0 ;
00235 for (j = 0 ; j < i ; j++)
00236 {
00237 if ( newID[isort[j]] > newID[isort[j+1]]) {
00238 int temp = isort[j];
00239 isort[j] = isort[j+1];
00240 isort[j+1] = temp;
00241
00242
00243
00244
00245
00246 k = j ;
00247 }
00248 }
00249 i = k ;
00250 } while ( k > 0) ;
00251
00252 i = 0 ;
00253 ipos = isort[i] ;
00254 k = rowblks[newID[ipos]] ;
00255 saveblk = begblk[k] ;
00256
00257 for (i=0; i<lnee; i++)
00258 {
00259 ipos = isort[i] ;
00260 i_eq = newID[ipos] ;
00261 iblk = rowblks[i_eq] ;
00262 iloc = penv[i_eq +1] - i_eq ;
00263 if (k < iblk)
00264 while (saveblk->row != i_eq)
00265 saveblk = saveblk->bnext ;
00266
00267 ptr = saveblk ;
00268 for (j=0; j< i ; j++)
00269 {
00270 jpos = isort[j] ;
00271 j_eq = newID[jpos] ;
00272
00273 if (ipos > jpos) {
00274 jt = ipos;
00275 it = jpos;
00276 } else {
00277 it = ipos;
00278 jt = jpos;
00279 }
00280
00281 if (j_eq >= xblk[iblk])
00282 { loc = iloc + j_eq ;
00283 *loc += m(it, jt) * fact;
00284 } else
00285 { while((j_eq >= (ptr->next)->beg) && ((ptr->next)->row == i_eq))
00286 ptr = ptr->next ;
00287 fpt = ptr->nz ;
00288 fpt[j_eq - ptr->beg] += m(it,jt) * fact;
00289 }
00290 }
00291 diag[i_eq] += m(ipos, ipos) * fact;
00292 }
00293
00294 delete [] newID;
00295 delete [] isort;
00296
00297 return 0;
00298 }
00299
00300
00301 int
00302 SymArpackSOE::addM(const Matrix &m, const ID &id, double fact)
00303 {
00304 return this->addA(m, id, -shift);
00305 }
00306
00307
00308 double
00309 SymArpackSOE::getShift(void)
00310 {
00311 return shift;
00312 }
00313
00314 void
00315 SymArpackSOE::zeroA(void)
00316 {
00317 factored = false;
00318 }
00319
00320 void
00321 SymArpackSOE::zeroM(void)
00322 {
00323
00324 }
00325
00326 int
00327 SymArpackSOE::sendSelf(int cTag, Channel &theChannel)
00328 {
00329 return 0;
00330 }
00331
00332 int
00333 SymArpackSOE::recvSelf(int cTag, Channel &theChannel,
00334 FEM_ObjectBroker &theBroker)
00335 {
00336 return 0;
00337 }
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349