DistributedSparseGenRowLinSOE.cppGo 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 |