DistributedSparseGenRowLinSOE.cpp

Go to the documentation of this file.
00001 /* ****************************************************************** **
00002 **    OpenSees - Open System for Earthquake Engineering Simulation    **
00003 **          Pacific Earthquake Engineering Research Center            **
00004 **                                                                    **
00005 **                                                                    **
00006 ** (C) Copyright 1999, The Regents of the University of California    **
00007 ** All Rights Reserved.                                               **
00008 **                                                                    **
00009 ** Commercial use of this program without express permission of the   **
00010 ** University of California, Berkeley, is strictly prohibited.  See   **
00011 ** file 'COPYRIGHT'  in main directory for information on usage and   **
00012 ** redistribution,  and for a DISCLAIMER OF ALL WARRANTIES.           **
00013 **                                                                    **
00014 ** Developed by:                                                      **
00015 **   Frank McKenna (fmckenna@ce.berkeley.edu)                         **
00016 **   Gregory L. Fenves (fenves@ce.berkeley.edu)                       **
00017 **   Filip C. Filippou (filippou@ce.berkeley.edu)                     **
00018 **                                                                    **
00019 ** ****************************************************************** */
00020                                                                         
00021 // $Revision: 1.2 $
00022 // $Date: 2006/10/02 20:23:22 $
00023 // $Source: /usr/local/cvs/OpenSees/SRC/system_of_eqn/linearSOE/sparseGEN/DistributedSparseGenRowLinSOE.cpp,v $
00024                                                                         
00025 // Written: fmk 
00026 // Created: 04/05
00027 //
00028 // Description: This file contains the implementation for DistributedSparseGenRowLinSOE
00029 
00030 #include <DistributedSparseGenRowLinSOE.h>
00031 #include <DistributedSparseGenRowLinSolver.h>
00032 #include <Matrix.h>
00033 #include <Graph.h>
00034 #include <Vertex.h>
00035 #include <VertexIter.h>
00036 #include <math.h>
00037 
00038 #include <Channel.h>
00039 #include <FEM_ObjectBroker.h>
00040 
00041 DistributedSparseGenRowLinSOE::DistributedSparseGenRowLinSOE(DistributedSparseGenRowLinSolver &the_Solver)
00042 :LinearSOE(the_Solver, LinSOE_TAGS_DistributedSparseGenRowLinSOE),
00043  n(0), nnz(0), A(0), B(0), X(0), colA(0), rowStartA(0),
00044  vectX(0), vectB(0),
00045  Asize(0), Bsize(0),
00046  factored(false),
00047  numP(0), rank(-1), startRow(-1), endRow(-1), numRows(0),
00048  rows(0), otherProcessesRows(0), otherProcessesRowStart(0)
00049 {
00050     the_Solver.setLinearSOE(*this);
00051 }
00052 
00053 
00054 DistributedSparseGenRowLinSOE::~DistributedSparseGenRowLinSOE()
00055 {
00056     if (A != 0) delete [] A;
00057     if (B != 0) delete [] B;
00058     if (X != 0) delete [] X;
00059     if (rowStartA != 0) delete [] rowStartA;
00060     if (colA != 0) delete []colA;
00061     if (vectX != 0) delete vectX;    
00062     if (vectB != 0) delete vectB;        
00063     if (otherProcessesRows != 0) delete [] otherProcessesRows;
00064     if (otherProcessesRowStart != 0) delete [] otherProcessesRowStart;
00065 }
00066 
00067 
00068 int
00069 DistributedSparseGenRowLinSOE::getNumEqn(void) const
00070 {
00071     return n;
00072 }
00073 
00074 int 
00075 DistributedSparseGenRowLinSOE::setSize(Graph &theGraph)
00076 {
00077   int result = 0;
00078   /*
00079   size = theGraph.getNumVertex();
00080 
00081   //
00082   // first we build an ID containing all local DOFs
00083   //
00084 
00085   myDOFs.resize(size);
00086 
00087   int count = 0;
00088   Vertex *theVertex;
00089   VertexIter &theVertices = theGraph.getVertices();
00090   while ((theVertex = theVertices()) != 0) {
00091     int vertexTag = theVertex->getTag();
00092     myDOFs(count) = vertexTag;
00093     count++;
00094   }
00095 
00096   static ID otherSize(1);
00097   ID otherDOFS(0, size/10);
00098 
00099   if (processID != 0) {
00100 
00101     //
00102     // each process send it's local and receives all other processes IDs (remote IDs).
00103     // from the remote IDs the local process figures out which DOF's it shares with others.
00104     // it then sends the shared dofs' out.
00105     //
00106 
00107     Channel *theChannel = theChannels[0];
00108     theChannel->recvID(0, 0, otherSize);
00109     numProcesses = otherSize(0);
00110 
00111     // send local
00112     otherSize(0) = size;
00113     theChannel->sendID(0, 0, otherSize);
00114     if (size != 0)
00115       theChannel->sendID(0, 0, myDOFs);
00116 
00117     for (int i=0; i<numProcesses-1; i++) {
00118       // receive remote & check for shared DOFs
00119       theChannel->recvID(0, 0, otherSize);      
00120       int numOther = otherSize(0);
00121       
00122       if (numOther != 0) {
00123         otherDOFS.resize(numOther);
00124         theChannel->recvID(0, 0, otherDOFS);
00125         
00126         for (int j=0; j<numOther; j++) {
00127           int otherTag = otherDOFS(j);
00128           if (myDOFs.getLocation(otherTag) != -1 && myDOFsShared.getLocation(otherTag) == -1) 
00129             myDOFsShared[numShared++] = otherTag;
00130         }
00131       }
00132     }
00133 
00134     // send my shared DOFs
00135     otherSize(0) = myDOFsShared.Size();
00136     theChannel->sendID(0, 0, otherSize);
00137     if (size != 0)
00138       theChannel->sendID(0, 0, myDOFsShared);
00139 
00140     // recv all shared DOFs
00141     theChannel->recvID(0, 0, otherSize);        
00142     int numShared = otherSize(0);
00143     if (numShared != 0) {
00144       myDOFsShared.resize(numShared);
00145       theChannel->recvID(0, 0, myDOFsShared);
00146     } 
00147 
00148   } else { // in absence of a broadcast we need the following
00149 
00150     //
00151     // each process send it's local and receives all other processes IDs (remote IDs).
00152     // from the remote IDs the local process figures out which DOF's it shares with others.
00153     // it then sends the shared dofs' out. lastly receives from P0 list of all shared.
00154     // NOTE:  if all sent to P0 their ID's; P0 could figure out shared; but scalability issues
00155     //
00156 
00157     for (int j=0; j<numChannels; j++) {
00158       Channel *theChannel = theChannels[j];
00159       otherSize(0) = numChannels+1;
00160       theChannel->sendID(0, 0, otherSize);
00161 
00162       otherSize(0) = size;
00163       theChannel->sendID(0, 0, otherSize);
00164       if (size != 0)
00165         theChannel->sendID(0, 0, myDOFs);
00166     }
00167 
00168     for (int j=0; j<numChannels; j++) {
00169       Channel *theChannel = theChannels[j];
00170 
00171       // receive remote & check for shared DOFs
00172 
00173       theChannel->recvID(0, 0, otherSize);      
00174       int numOther = otherSize(0);
00175       if (numOther != 0) {
00176         otherDOFS.resize(numOther);
00177         theChannel->recvID(0, 0, otherDOFS);
00178       }
00179 
00180       // need to send to all others
00181       for (int k=0; k<numChannels; k++) {
00182         Channel *theChannel = theChannels[k];
00183         if (k != j) {
00184           theChannel->sendID(0, 0, otherSize);  
00185           if (numOther != 0) {
00186             theChannel->sendID(0, 0, otherDOFS);            
00187           }
00188         }
00189       }
00190       
00191       // need to merge with mine 
00192       for (int l=0; l<numOther; l++) {
00193         int otherTag = otherDOFS(l);
00194         if (myDOFs.getLocation(otherTag) != -1 && myDOFsShared.getLocation(otherTag) == -1) { 
00195           myDOFsShared[numShared++] = otherTag;
00196         }
00197       }
00198     }
00199 
00200     // now recv each of the shared DOFs & merge with mine to form the master list
00201     for (int j=0; j<numChannels; j++) {
00202       Channel *theChannel = theChannels[j];
00203       theChannel->recvID(0, 0, otherSize);      
00204       int numOther = otherSize(0);
00205       if (numOther != 0) {
00206         otherDOFS.resize(numOther);
00207         theChannel->recvID(0, 0, otherDOFS);
00208       } 
00209       // need to merge with mine 
00210       for (int k=0; k<numOther; k++) {
00211         int otherTag = otherDOFS(k);
00212         if (myDOFsShared.getLocation(otherTag) == -1) 
00213           myDOFsShared(numShared++) = otherTag;
00214       }
00215     }
00216 
00217     // now send the shared ID
00218     for (int j=0; j<numChannels; j++) {
00219       Channel *theChannel = theChannels[j];
00220       otherSize(0) = numShared;
00221       theChannel->sendID(0, 0, otherSize);      
00222       theChannel->sendID(0, 0, myDOFsShared);
00223     } 
00224   }
00225 
00226   //
00227   // now master list has been created we recv from each process the edges corresponding
00228   // to shared vertices.
00229   // 
00230 
00231 
00232 
00233   // 
00234   // determine system size
00235   //
00236   
00237   // first determine the largest in graph on local
00238   int myN = 0;
00239   VertexIter &theVertices = theGraph.getVertices();
00240   Vertex *theVertex;
00241   while ((theVertex = theVertices()) != 0) {
00242     if (theVertex->getTag() > myN)
00243       myN = theVertex->getTag();
00244   }
00245     
00246   // each process sends local, n is max of them all
00247   n = myN;
00248   for (int i=0; i<numP; i++) {
00249     static ID rankSendRecv(1);
00250     if (rank == i) {
00251       rankSendRecv = myN;
00252       theChannel->sendID(0,0,rankSendRecv);
00253     } else {
00254       theChannel->recvID(0,0,rankSendRecv);
00255       if (rankSendRecv(0) > n)
00256         n = rankSendRecv(0);
00257     }
00258   }
00259   
00260   //
00261   // now determine rows assigned to each process
00262   //
00263   
00264   numRows = n/numP;
00265   startRow = numRows*rank;
00266     endRow = numRows*(rank+1);
00267   } else {
00268     startRow = numRows*(numP-1);
00269     endRow = n;
00270   }
00271   
00272   numRows = endRow-startRow;
00273 
00274     //
00275     // now create a graph of all rows assigned to processor & any rows
00276     // that are included from local graph (theGraph passed in method call)
00277     //
00278 
00279     //
00280     // graph must obviously contain the original plus any new Vertices from startRow
00281     // through endRow not already in Graph; rows ID must also contain any vertex in Graph
00282     // but not in current startRow through endRow.
00283     //
00284 
00285     Graph myGraph(theGraph);
00286     rows.resize(numRows);
00287 
00288     for (int i=0; i<numRows; i++) {
00289       int row = startRow + i;
00290       rows(i) = row;
00291       if ((theVertex = myGraph.getVertexPtr(row)) == 0) {
00292         theVertex = new Vertex(row, row);
00293         if (myGraph.addVertex(theVertex, false) == false) {
00294           opserr << "WARNING DistributedDistributedSparseGenRowLinSOE::addVertex - error adding vertex\n";
00295         }
00296       }
00297     }
00298       
00299     int numAllRows = numRows;
00300     VertexIter &theVertices2 = myGraph.getVertices();
00301     while ((theVertex = theVertices2()) != 0) {      
00302       int row = theVertex->getTag();
00303       int rowLoc = rows.getLocation(row);
00304       if (rowLoc == -1) {
00305         rows[numAllRows] = row;
00306         numAllRows++;
00307       }
00308     }
00309 
00310     rowStartA = new int[numAllRows+1]; 
00311 
00312     // graph must also contain all edges that exist in other graphs for vertices
00313     // in numRows; we will only add edges & not vertices; graph will end up undirected
00314     // which is why we can't use addEdge Graph method but must add edges to Vertices
00315 
00316     for (int i=0; i<numP; i++) {
00317       if (rank == i) {
00318 
00319         //
00320         // of course we only need to send the vertices of the graph that we are not responsible for!
00321         //
00322 
00323         Graph graphToSend;
00324         Vertex *theVertex;
00325         VertexIter &theVertices = theGraph.getVertices();       
00326         while ((theVertex = theVertices()) != 0) {
00327           int vertexTag = theVertex->getTag();
00328           if (vertexTag < startRow && vertexTag >= endRow) {
00329             Vertex *copyVertex = new Vertex(*theVertex);
00330             graphToSend.addVertex(copyVertex, false);
00331           }
00332         }
00333 
00334         // now send this new graph
00335         graphToSend.sendSelf(0, *theChannel);
00336       } else {
00337 
00338         // receive the graph, for each vertex in recvd graph, if vertex is in myGraph
00339         // add any edges not already present in newly recvd graph to vertex in myGraph.
00340 
00341         FEM_ObjectBroker theBroker;
00342         Graph otherGraph;
00343         otherGraph.recvSelf(0, *theChannel, theBroker);
00344         VertexIter &theVertices = otherGraph.getVertices();
00345         Vertex *otherVertex;
00346         while ((otherVertex = theVertices()) != 0) {
00347           int otherTag = otherVertex->getTag();
00348           int otherTagLoc = rows.getLocation(otherTag);
00349           if (otherTagLoc >= 0) {
00350             theVertex = myGraph.getVertexPtr(otherTag);
00351             const ID &otherAdjacency = otherVertex->getAdjacency();
00352             for (int j=0; j<otherAdjacency.Size(); j++) {
00353               theVertex->addEdge(otherAdjacency(j));
00354             }
00355           }
00356         }
00357       }
00358     }
00359 
00360     int newNNZ = 0;
00361     VertexIter &theVertices3 = myGraph.getVertices();
00362     while ((theVertex = theVertices3()) != 0) {
00363         const ID &theAdjacency = theVertex->getAdjacency();
00364         newNNZ += theAdjacency.Size() +1; // the +1 is for the diag entry
00365     }
00366     nnz = newNNZ;
00367 
00368     if (newNNZ > Asize) { // we have to get more space for A and colA
00369         if (A != 0) 
00370             delete [] A;
00371         if (colA != 0)
00372             delete [] colA;
00373         
00374         A = new double[newNNZ];
00375         colA = new int[newNNZ];
00376         
00377         if (A == 0 || colA == 0) {
00378             opserr << "WARNING DistributedSparseGenRowLinSOE::DistributedSparseGenRowLinSOE :";
00379             opserr << " ran out of memory for A and colA with nnz = ";
00380             opserr << newNNZ << " \n";
00381             n = 0; Asize = 0; nnz = 0;
00382             result =  -1;
00383         } 
00384         
00385         Asize = newNNZ;
00386     }
00387 
00388     // zero the matrix
00389     for (int i=0; i<Asize; i++)
00390         A[i] = 0;
00391         
00392     factored = false;
00393     
00394     if (n > Bsize) { // we have to get space for the vectors
00395         
00396         // delete the old       
00397         if (B != 0) delete [] B;
00398         if (X != 0) delete [] X;
00399         if (rowStartA != 0) delete [] rowStartA;
00400 
00401         // create the new
00402         B = new double[n];
00403         X = new double[n];
00404         
00405         if (B == 0 || X == 0) {
00406             opserr << "WARNING DistributedSparseGenRowLinSOE::DistributedSparseGenRowLinSOE :";
00407             opserr << " ran out of memory for vectors (size) (";
00408             opserr << n << ") \n";
00409             n = 0; Bsize = 0;
00410             result =  -1;
00411         }
00412         else
00413             Bsize = n;
00414     }
00415 
00416     // zero the vectors
00417     for (int j=0; j<n; j++) {
00418         B[j] = 0;
00419         X[j] = 0;
00420     }
00421     
00422     // create new Vectors objects
00423     if (n != oldSize) {
00424         if (vectX != 0)
00425             delete vectX;
00426 
00427         if (vectB != 0)
00428             delete vectB;
00429         
00430         vectX = new Vector(X, n);
00431         vectB = new Vector(B, n);       
00432     }
00433 
00434     // fill in rowStartA and colA
00435     if (n != 0) {
00436       rowStartA[0] = 0;
00437       int startLoc = 0;
00438       int lastLoc = 0;
00439       for (int a=0; a<numAllRows; a++) {
00440 
00441         theVertex = theGraph.getVertexPtr(rows(a));
00442         if (theVertex == 0) {
00443           opserr << "WARNING:DistributedSparseGenRowLinSOE::setSize :";
00444           opserr << " vertex " << a << " not in graph! - n set to 0\n";
00445           n = 0;
00446           return -1;
00447         }
00448 
00449         colA[lastLoc++] = theVertex->getTag(); // place diag in first
00450         const ID &theAdjacency = theVertex->getAdjacency();
00451         int idSize = theAdjacency.Size();
00452         
00453         // now we have to place the entries in the ID into order in colA
00454         for (int i=0; i<idSize; i++) {
00455 
00456           int row = theAdjacency(i);
00457           bool foundPlace = false;
00458           // find a place in colA for current col
00459           for (int j=startLoc; j<lastLoc; j++)
00460             if (colA[j] > row) { 
00461               // move the entries already there one further on
00462               // and place col in current location
00463               for (int k=lastLoc; k>j; k--)
00464                 
00465                 colA[k] = colA[k-1];
00466               colA[j] = row;
00467               foundPlace = true;
00468               j = lastLoc;
00469             }
00470           if (foundPlace == false) // put in at the end
00471             colA[lastLoc] = row;
00472 
00473           lastLoc++;
00474         }
00475         rowStartA[a+1] = lastLoc;;          
00476         startLoc = lastLoc;
00477       }
00478     }
00479     
00480     // invoke setSize() on the Solver    
00481     LinearSOESolver *the_Solver = this->getSolver();
00482     int solverOK = the_Solver->setSize();
00483     if (solverOK < 0) {
00484         opserr << "WARNING:DistributedSparseGenRowLinSOE::setSize :";
00485         opserr << " solver failed setSize()\n";
00486         return solverOK;
00487     }    
00488   */
00489     return result;
00490 }
00491 
00492 int 
00493 DistributedSparseGenRowLinSOE::addA(const Matrix &m, const ID &id, double fact)
00494 {
00495     // check for a quick return 
00496     if (fact == 0.0)  
00497         return 0;
00498 
00499     int idSize = id.Size();
00500     
00501     // check that m and id are of similar n
00502     if (idSize != m.noRows() && idSize != m.noCols()) {
00503         opserr << "DistributedSparseGenRowLinSOE::addA() ";
00504         opserr << " - Matrix and ID not of similar ns\n";
00505         return -1;
00506     }
00507     
00508     for (int i=0; i<idSize; i++) {
00509       int row = id(i);
00510       if (row < n && row >= 0) {
00511         int localRow = rows.getLocation(row);
00512         if (localRow == -1) 
00513           opserr << "DistributedSparseGenRowLinSOE::addA() - you goofed\n";
00514         int startRowLoc = rowStartA[localRow];
00515         int endRowLoc = rowStartA[localRow+1];
00516         for (int j=0; j<idSize; j++) {
00517           int col = id(j);
00518           if ((col < n) && (col >= 0)) {
00519             // find place in A using colA
00520             for (int k=startRowLoc; k<endRowLoc; k++)
00521               if (colA[k] == col) {
00522                 A[k] += m(i,j) * fact;
00523                 k = endRowLoc;
00524               }
00525           }
00526         }  // for j             
00527       } 
00528     }  // for i
00529 
00530     return 0;
00531 }
00532 
00533     
00534 int 
00535 DistributedSparseGenRowLinSOE::addB(const Vector &v, const ID &id, double fact)
00536 {
00537     // check for a quick return 
00538     if (fact == 0.0)  return 0;
00539 
00540     int idSize = id.Size();    
00541     // check that m and id are of similar n
00542     if (idSize != v.Size() ) {
00543         opserr << "DistributedSparseGenRowLinSOE::addB() ";
00544         opserr << " - Vector and ID not of similar ns\n";
00545         return -1;
00546     }    
00547 
00548     if (fact == 1.0) { // do not need to multiply if fact == 1.0
00549         for (int i=0; i<idSize; i++) {
00550             int pos = id(i);
00551             if (pos < n && pos >= 0)
00552                 B[pos] += v(i);
00553         }
00554     } else if (fact == -1.0) { // do not need to multiply if fact == -1.0
00555         for (int i=0; i<idSize; i++) {
00556             int pos = id(i);
00557             if (pos <n && pos >= 0)
00558                 B[pos] -= v(i);
00559         }
00560     } else {
00561         for (int i=0; i<idSize; i++) {
00562             int pos = id(i);
00563             if (pos <n && pos >= 0)
00564                 B[pos] += v(i) * fact;
00565         }
00566     }   
00567 
00568     return 0;
00569 }
00570 
00571 
00572 int
00573 DistributedSparseGenRowLinSOE::setB(const Vector &v, double fact)
00574 {
00575     // check for a quick return 
00576     if (fact == 0.0)  return 0;
00577 
00578 
00579     if (v.Size() != n) {
00580         opserr << "WARNING BandGenLinSOE::setB() -";
00581         opserr << " incomptable ns " << n << " and " << v.Size() << endln;
00582         return -1;
00583     }
00584     
00585     if (fact == 1.0) { // do not need to multiply if fact == 1.0
00586         for (int i=0; i<n; i++) {
00587             B[i] = v(i);
00588         }
00589     } else if (fact == -1.0) {
00590         for (int i=0; i<n; i++) {
00591             B[i] = -v(i);
00592         }
00593     } else {
00594         for (int i=0; i<n; i++) {
00595             B[i] = v(i) * fact;
00596         }
00597     }   
00598     return 0;
00599 }
00600 
00601 void 
00602 DistributedSparseGenRowLinSOE::zeroA(void)
00603 {
00604     double *Aptr = A;
00605     for (int i=0; i<Asize; i++)
00606         *Aptr++ = 0;
00607 
00608     factored = false;
00609 }
00610         
00611 void 
00612 DistributedSparseGenRowLinSOE::zeroB(void)
00613 {
00614     double *Bptr = B;
00615     for (int i=0; i<n; i++)
00616         *Bptr++ = 0;
00617 }
00618 
00619 void 
00620 DistributedSparseGenRowLinSOE::setX(int loc, double value)
00621 {
00622     if (loc < n && loc >=0)
00623         X[loc] = value;
00624 }
00625 
00626 void 
00627 DistributedSparseGenRowLinSOE::setX(const Vector &x)
00628 {
00629   if (x.Size() == n && vectX != 0)
00630     *vectX = x;
00631 }
00632 
00633 const Vector &
00634 DistributedSparseGenRowLinSOE::getX(void)
00635 {
00636     if (vectX == 0) {
00637         opserr << "FATAL DistributedSparseGenRowLinSOE::getX - vectX == 0";
00638         exit(-1);
00639     }
00640     return *vectX;
00641 }
00642 
00643 const Vector &
00644 DistributedSparseGenRowLinSOE::getB(void)
00645 {
00646     if (vectB == 0) {
00647         opserr << "FATAL DistributedSparseGenRowLinSOE::getB - vectB == 0";
00648         exit(-1);
00649     }        
00650     return *vectB;
00651 }
00652 
00653 double 
00654 DistributedSparseGenRowLinSOE::normRHS(void)
00655 {
00656     double norm =0.0;
00657     for (int i=0; i<n; i++) {
00658         double Yi = B[i];
00659         norm += Yi*Yi;
00660     }
00661     return sqrt(norm);
00662     
00663 }    
00664 
00665 
00666 int
00667 DistributedSparseGenRowLinSOE::setDistributedSparseGenRowSolver(DistributedSparseGenRowLinSolver &newSolver)
00668 {
00669     newSolver.setLinearSOE(*this);
00670     
00671     if (n != 0) {
00672         int solverOK = newSolver.setSize();
00673         if (solverOK < 0) {
00674             opserr << "WARNING:DistributedSparseGenRowLinSOE::setSolver :";
00675             opserr << "the new solver could not setSeize() - staying with old\n";
00676             return -1;
00677         }
00678     }
00679     
00680     return this->LinearSOE::setSolver(newSolver);
00681 }
00682 
00683 
00684 int 
00685 DistributedSparseGenRowLinSOE::sendSelf(int cTag, Channel &theChannel)
00686 {
00687   processID = 0;
00688   int sendID =0;
00689 
00690   // if P0 check if already sent. If already sent use old processID; if not allocate a new process 
00691   // id for remote part of object, enlarge channel * to hold a channel * for this remote object.
00692 
00693   // if not P0, send current processID
00694 
00695   if (processID == 0) {
00696 
00697     // check if already using this object
00698     bool found = false;
00699     for (int i=0; i<numChannels; i++)
00700       if (theChannels[i] == &theChannel) {
00701         sendID = i+1;
00702         found = true;
00703       }
00704 
00705     // if new object, enlarge Channel pointers to hold new channel * & allocate new ID
00706     if (found == false) {
00707       int nextNumChannels = numChannels + 1;
00708       Channel **nextChannels = new Channel *[nextNumChannels];
00709       if (nextNumChannels == 0) {
00710         opserr << "DistributedBandGenLinSOE::sendSelf() - failed to allocate channel array of size: " << 
00711           nextNumChannels << endln;
00712         return -1;
00713       }
00714       for (int i=0; i<numChannels; i++)
00715         nextChannels[i] = theChannels[i];
00716       nextChannels[numChannels] = &theChannel;
00717       numChannels = nextNumChannels;
00718       
00719       if (theChannels != 0)
00720         delete [] theChannels;
00721       
00722       theChannels = nextChannels;
00723       
00724   if (localCol != 0)
00725         delete [] localCol;
00726       localCol = new ID *[numChannels];
00727       if (localCol == 0) {
00728         opserr << "DistributedBandGenLinSOE::sendSelf() - failed to allocate id array of size: " << 
00729           nextNumChannels << endln;
00730         return -1;
00731       }
00732       for (int i=0; i<numChannels; i++)
00733         localCol[i] = 0;    
00734 
00735       // allocate new processID for remote object
00736       sendID = numChannels;
00737     }
00738 
00739   } else 
00740     sendID = processID;
00741 
00742   return 0;
00743 }
00744 
00745 
00746 int 
00747 DistributedSparseGenRowLinSOE::recvSelf(int cTag, Channel &theChannel, 
00748                    FEM_ObjectBroker &theBroker)
00749 {
00750   numChannels = 1;
00751   theChannels = new Channel *[1];
00752   theChannels[0] = &theChannel;
00753 
00754   localCol = new ID *[numChannels];
00755   for (int i=0; i<numChannels; i++)
00756     localCol[i] = 0;
00757 
00758   return 0;
00759 }
00760 
00761 int
00762 DistributedSparseGenRowLinSOE::setChannels(int nChannels, Channel **theC)
00763 {
00764   numChannels = nChannels;
00765 
00766   if (theChannels != 0)
00767     delete [] theChannels;
00768 
00769   theChannels = new Channel *[numChannels];
00770   for (int i=0; i<numChannels; i++)
00771     theChannels[i] = theC[i];
00772 
00773 
00774   localCol = new ID *[nChannels];
00775   for (int i=0; i<numChannels; i++)
00776     localCol[i] = 0;
00777 
00778   return 0;
00779 }
00780 
00781 
00782 

Generated on Mon Oct 23 15:05:29 2006 for OpenSees by doxygen 1.5.0