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
00036 #include <RCM.h>
00037 #include <Graph.h>
00038 #include <Vertex.h>
00039 #include <VertexIter.h>
00040 #include <ID.h>
00041 #include <Channel.h>
00042 #include <FEM_ObjectBroker.h>
00043
00044
00045 RCM::RCM(bool gps)
00046 :GraphNumberer(GraphNUMBERER_TAG_RCM),
00047 numVertex(-1), theRefResult(0), GPS(gps)
00048 {
00049
00050 }
00051
00052
00053 RCM::~RCM()
00054 {
00055 if (theRefResult != 0)
00056 delete theRefResult;
00057 }
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072 const ID &
00073 RCM::number(Graph &theGraph, int startVertex)
00074 {
00075
00076 if (numVertex != theGraph.getNumVertex()) {
00077
00078
00079 if (theRefResult != 0)
00080 delete theRefResult;
00081
00082 numVertex = theGraph.getNumVertex();
00083 theRefResult = new ID(numVertex);
00084
00085 if (theRefResult == 0) {
00086 opserr << "ERROR: RCM::number - Out of Memory\n";
00087 theRefResult = new ID(0);
00088 numVertex = 0;
00089 return *theRefResult;
00090 }
00091 }
00092
00093
00094
00095 if (numVertex == 0)
00096 return *theRefResult;
00097
00098
00099
00100
00101
00102 Vertex *vertexPtr;
00103 VertexIter &vertexIter = theGraph.getVertices();
00104
00105 while ((vertexPtr = vertexIter()) != 0)
00106 vertexPtr->setTmp(-1);
00107
00108
00109 int startVertexTag;
00110 startVertexTag = startVertex;
00111
00112 if (startVertexTag != -1) {
00113 vertexPtr = theGraph.getVertexPtr(startVertexTag);
00114 if (vertexPtr == 0) {
00115 opserr << "WARNING: RCM::number - No vertex with tag ";
00116 opserr << startVertexTag << "Exists - using first come from iter\n";
00117 startVertexTag = -1;
00118 }
00119 }
00120
00121
00122 VertexIter &vertexIter2 = theGraph.getVertices();
00123 Vertex *start;
00124
00125 if (startVertexTag == -1) {
00126 vertexPtr = vertexIter2();
00127 start = vertexPtr;
00128
00129
00130
00131
00132 if (GPS == true) {
00133
00134 int currentMark = numVertex-1;
00135 int nextMark = currentMark -1;
00136 int startLastLevelSet = nextMark;
00137 (*theRefResult)(currentMark) = vertexPtr->getTag();
00138 vertexPtr->setTmp(currentMark);
00139
00140
00141
00142 while (nextMark >= 0) {
00143
00144
00145 vertexPtr = theGraph.getVertexPtr((*theRefResult)(currentMark));
00146 const ID &adjacency = vertexPtr->getAdjacency();
00147
00148
00149
00150
00151 int size = adjacency.Size();
00152 for (int i=0; i<size; i++) {
00153
00154 int vertexTag = adjacency(i);
00155 vertexPtr = theGraph.getVertexPtr(vertexTag);
00156 if ((vertexPtr->getTmp()) == -1) {
00157 vertexPtr->setTmp(nextMark);
00158 (*theRefResult)(nextMark--) = vertexTag;
00159 }
00160 }
00161
00162
00163
00164
00165 currentMark--;
00166
00167 if (startLastLevelSet == currentMark)
00168 startLastLevelSet = nextMark;
00169
00170
00171
00172 if ((currentMark == nextMark) && (currentMark >= 0)) {
00173
00174
00175 while (((vertexPtr = vertexIter2()) != 0) &&
00176 (vertexPtr->getTmp() != -1))
00177 ;
00178
00179 nextMark--;
00180 startLastLevelSet = nextMark;
00181 vertexPtr->setTmp(currentMark);
00182 (*theRefResult)(currentMark) = vertexPtr->getTag();
00183
00184 }
00185
00186 }
00187
00188
00189 if (startLastLevelSet > 0) {
00190 ID lastLevelSet(startLastLevelSet);
00191 for (int i=0; i<startLastLevelSet; i++)
00192 lastLevelSet(i) = (*theRefResult)(i);
00193
00194 return this->number(theGraph,lastLevelSet);
00195 }
00196
00197 }
00198 else
00199 vertexPtr = start;
00200 }
00201
00202
00203 VertexIter &vertexIter3 = theGraph.getVertices();
00204 Vertex *otherPtr;
00205
00206
00207 while ((otherPtr = vertexIter3()) != 0)
00208 otherPtr->setTmp(-1);
00209
00210
00211 VertexIter &vertexIter4 = theGraph.getVertices();
00212
00213 int currentMark = numVertex-1;
00214 int nextMark = currentMark -1;
00215 (*theRefResult)(currentMark) = vertexPtr->getTag();
00216 vertexPtr->setTmp(currentMark);
00217
00218
00219 while (nextMark >= 0) {
00220
00221 vertexPtr = theGraph.getVertexPtr((*theRefResult)(currentMark));
00222 const ID &adjacency = vertexPtr->getAdjacency();
00223
00224
00225
00226
00227 int size = adjacency.Size();
00228 for (int i=0; i<size; i++) {
00229
00230 int vertexTag = adjacency(i);
00231 vertexPtr = theGraph.getVertexPtr(vertexTag);
00232 if ((vertexPtr->getTmp()) == -1) {
00233 vertexPtr->setTmp(nextMark);
00234 (*theRefResult)(nextMark--) = vertexTag;
00235 }
00236 }
00237
00238
00239
00240
00241 currentMark--;
00242
00243
00244
00245 if ((currentMark == nextMark) && (currentMark >= 0)) {
00246
00247
00248
00249
00250 while (((vertexPtr = vertexIter4()) != 0) &&
00251 (vertexPtr->getTmp() != -1))
00252 ;
00253
00254 nextMark--;
00255 vertexPtr->setTmp(currentMark);
00256 (*theRefResult)(currentMark) = vertexPtr->getTag();
00257 }
00258
00259 }
00260
00261
00262
00263
00264 for (int i=0; i<numVertex; i++) {
00265 int vertexTag = (*theRefResult)(i);
00266 vertexPtr = theGraph.getVertexPtr(vertexTag);
00267 vertexPtr->setTmp(i+1);
00268 (*theRefResult)(i) = vertexPtr->getTag();
00269 }
00270
00271 return *theRefResult;
00272 }
00273
00274
00275
00276 int
00277 RCM::sendSelf(int commitTag, Channel &theChannel)
00278 {
00279 return 0;
00280 }
00281
00282 int
00283 RCM::recvSelf(int commitTag, Channel &theChannel, FEM_ObjectBroker &theBroker)
00284 {
00285 return 0;
00286 }
00287
00288
00289 const ID &
00290 RCM::number(Graph &theGraph, const ID &startVertices)
00291 {
00292
00293
00294 if (numVertex != theGraph.getNumVertex()) {
00295
00296
00297 if (theRefResult != 0)
00298 delete theRefResult;
00299
00300 numVertex = theGraph.getNumVertex();
00301 theRefResult = new ID(numVertex);
00302
00303 if (theRefResult == 0) {
00304 opserr << "ERROR: RCM::number - Out of Memory\n";
00305 theRefResult = new ID(0);
00306 numVertex = 0;
00307 return *theRefResult;
00308 }
00309 }
00310
00311
00312
00313 if (numVertex == 0)
00314 return *theRefResult;
00315
00316
00317 int minStartVertexTag =0;
00318 int minAvgProfile = 0;
00319 int startVerticesSize = startVertices.Size();
00320 Vertex *vertexPtr;
00321
00322 int startVertexTag =0;
00323
00324 for (int i=0; i<startVerticesSize; i++) {
00325
00326
00327 VertexIter &vertexIter = theGraph.getVertices();
00328
00329 while ((vertexPtr = vertexIter()) != 0)
00330 vertexPtr->setTmp(-1);
00331
00332 startVertexTag = startVertices(i);
00333
00334 if (startVertexTag != -1) {
00335 vertexPtr = theGraph.getVertexPtr(startVertexTag);
00336 if (vertexPtr == 0) {
00337 opserr << "WARNING: RCM::number - No vertex with tag ";
00338 opserr << startVertexTag << "Exists - using first come from iter\n";
00339 startVertexTag = -1;
00340 }
00341 }
00342
00343 int currentMark = numVertex-1;
00344 int nextMark = currentMark -1;
00345 (*theRefResult)(currentMark) = vertexPtr->getTag();
00346 vertexPtr->setTmp(currentMark);
00347 int avgProfile = 0;
00348 VertexIter &vertexIter2 = theGraph.getVertices();
00349
00350
00351
00352 while (nextMark >= 0) {
00353
00354
00355 vertexPtr = theGraph.getVertexPtr((*theRefResult)(currentMark));
00356 const ID &adjacency = vertexPtr->getAdjacency();
00357
00358
00359
00360
00361 int size = adjacency.Size();
00362 for (int j=0; j<size; j++) {
00363
00364 int vertexTag = adjacency(j);
00365 vertexPtr = theGraph.getVertexPtr(vertexTag);
00366 if ((vertexPtr->getTmp()) == -1) {
00367 vertexPtr->setTmp(nextMark);
00368 avgProfile += (currentMark - nextMark);
00369 (*theRefResult)(nextMark--) = vertexTag;
00370 }
00371 }
00372
00373
00374
00375
00376 currentMark--;
00377
00378
00379
00380 if ((currentMark == nextMark) && (currentMark >= 0)) {
00381
00382
00383
00384 while (((vertexPtr = vertexIter2()) != 0) &&
00385 (vertexPtr->getTmp() != -1))
00386 ;
00387 nextMark--;
00388
00389 vertexPtr->setTmp(currentMark);
00390 (*theRefResult)(currentMark) = vertexPtr->getTag();
00391 }
00392
00393 }
00394
00395 if (i == 0 || minAvgProfile > avgProfile) {
00396 minStartVertexTag = startVertexTag;
00397 minAvgProfile = avgProfile;
00398 }
00399
00400 }
00401
00402
00403
00404 minAvgProfile = 0;
00405
00406 if (minStartVertexTag != startVertexTag) {
00407
00408
00409
00410 startVertexTag = minStartVertexTag;
00411
00412
00413 VertexIter &vertexIter = theGraph.getVertices();
00414 while ((vertexPtr = vertexIter()) != 0)
00415 vertexPtr->setTmp(-1);
00416
00417 vertexPtr = theGraph.getVertexPtr(startVertexTag);
00418
00419 int currentMark = numVertex-1;
00420 int nextMark = currentMark -1;
00421 (*theRefResult)(currentMark) = vertexPtr->getTag();
00422 vertexPtr->setTmp(currentMark);
00423 VertexIter &vertexIter2 = theGraph.getVertices();
00424
00425
00426
00427 while (nextMark >= 0) {
00428
00429
00430
00431 vertexPtr = theGraph.getVertexPtr((*theRefResult)(currentMark));
00432 const ID &adjacency = vertexPtr->getAdjacency();
00433
00434
00435
00436
00437 int size = adjacency.Size();
00438 for (int j=0; j<size; j++) {
00439
00440 int vertexTag = adjacency(j);
00441 vertexPtr = theGraph.getVertexPtr(vertexTag);
00442 if ((vertexPtr->getTmp()) == -1) {
00443 vertexPtr->setTmp(nextMark);
00444 minAvgProfile += (currentMark-nextMark);
00445 (*theRefResult)(nextMark--) = vertexTag;
00446 }
00447 }
00448
00449
00450
00451
00452 currentMark--;
00453
00454
00455 if ((currentMark == nextMark) && (currentMark >= 0)) {
00456
00457
00458 while (((vertexPtr = vertexIter2()) != 0) &&
00459 (vertexPtr->getTmp() != -1))
00460 ;
00461
00462 nextMark--;
00463 vertexPtr->setTmp(currentMark);
00464 (*theRefResult)(currentMark) = vertexPtr->getTag();
00465 }
00466 }
00467 }
00468
00469
00470
00471
00472
00473 for (int j=0; j<numVertex; j++) {
00474 int vertexTag = (*theRefResult)(j);
00475 vertexPtr = theGraph.getVertexPtr(vertexTag);
00476 vertexPtr->setTmp(j+1);
00477 (*theRefResult)(j) = vertexPtr->getTag();
00478 }
00479
00480 return *theRefResult;
00481 }
00482
00483
00484
00485
00486
00487
00488
00489
00490