DistributedProfileSPDLinSOE.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.1 $
00022 // $Date: 2005/12/06 22:07:52 $
00023 // $Source: /usr/local/cvs/OpenSees/SRC/system_of_eqn/linearSOE/profileSPD/DistributedProfileSPDLinSOE.cpp,v $
00024                                                                         
00025 // Written: fmk 
00026 // Revision: A
00027 //
00028 // Description: This file contains the implementation for DistributedProfileSPDLinSOE
00029 
00030 #include <DistributedProfileSPDLinSOE.h>
00031 #include <ProfileSPDLinSolver.h>
00032 #include <Matrix.h>
00033 #include <Graph.h>
00034 #include <Vertex.h>
00035 #include <VertexIter.h>
00036 #include <f2c.h>
00037 #include <math.h>
00038 #include <Channel.h>
00039 #include <FEM_ObjectBroker.h>
00040 
00041 DistributedProfileSPDLinSOE::DistributedProfileSPDLinSOE(ProfileSPDLinSolver &theSolvr)
00042   :ProfileSPDLinSOE(theSolvr, LinSOE_TAGS_DistributedProfileSPDLinSOE), 
00043    processID(0), numChannels(0), theChannels(0), 
00044    localCol(0), sizeLocal(0), workArea(0), sizeWork(0), myVectB(0), myB(0)
00045 {
00046     theSolvr.setLinearSOE(*this);
00047 }
00048 
00049 
00050 DistributedProfileSPDLinSOE::~DistributedProfileSPDLinSOE()
00051 {
00052   if (theChannels != 0)
00053     delete [] theChannels;
00054 
00055   if (localCol != 0)
00056     for (int i=0; i<numChannels; i++)
00057       if (localCol[i] != 0)
00058         delete localCol[i];
00059   delete [] localCol;
00060 
00061   if (sizeLocal != 0)
00062     delete sizeLocal;
00063 
00064   if (workArea != 0)
00065     delete [] workArea;
00066 
00067   if (myVectB != 0)
00068     delete myVectB;
00069 
00070   if (myB != 0)
00071     delete [] myB;
00072 }
00073 
00074 
00075 int 
00076 DistributedProfileSPDLinSOE::setSize(Graph &theGraph)
00077 {
00078   int result = 0;
00079   int oldSize = size;
00080   int maxNumSubVertex = 0;
00081   int myProfileSize =0;
00082 
00083   // if subprocess, collect graph, send it off, 
00084   // vector back containing size of system, etc.
00085   if (processID != 0) {
00086     Channel *theChannel = theChannels[0];
00087     theGraph.sendSelf(0, *theChannel);
00088     
00089     static ID data(1);
00090     theChannel->recvID(0, 0, data);
00091     size = data(0);
00092 
00093     if (size > Bsize) { 
00094         if (iDiagLoc != 0) delete [] iDiagLoc;
00095         iDiagLoc = new int[size];
00096     }
00097     
00098     // receive my iDiagLoad
00099     ID iLoc(size);    
00100     theChannel->recvID(0, 0, iLoc);
00101 
00102     // determine iDiagLoc, profileSize & local mapping
00103     ID *subMap = new ID(theGraph.getNumVertex());
00104     localCol[0] = subMap;
00105     Vertex *vertex;
00106     VertexIter &theSubVertices = theGraph.getVertices();
00107     int cnt = 0; int loc = 0;  
00108     while((vertex = theSubVertices()) != 0) {
00109       int vertexTag = vertex->getTag();
00110       (*subMap)(cnt) = vertexTag;
00111       int colHeight =0;
00112       if (vertexTag == 0) {
00113         myProfileSize++;
00114         colHeight= 1;
00115       } else {
00116         colHeight = iLoc[vertexTag] - iLoc[vertexTag-1];            
00117         myProfileSize += colHeight;
00118       }
00119       loc += colHeight;
00120       iDiagLoc[cnt++] = loc;          
00121     }
00122     (*sizeLocal)(0) = myProfileSize;
00123 
00124     // send local mapping & profile size to P0
00125     theChannel->sendID(0, 0, *subMap);
00126     theChannel->sendID(0, 0, *sizeLocal);
00127   } 
00128   
00129   // if main domain, collect graphs from all subdomains,
00130   // merge into 1, number this one, send to subdomains the
00131   // id containing dof tags & start id's.
00132   else {
00133 
00134     // from each distributed soe recv it's graph
00135     // and merge them into master graph
00136 
00137     FEM_ObjectBroker theBroker;
00138     for (int j=0; j<numChannels; j++) {
00139       Channel *theChannel = theChannels[j];
00140       Graph theSubGraph;
00141       theSubGraph.recvSelf(0, *theChannel, theBroker);
00142       theGraph.merge(theSubGraph);
00143 
00144       int numSubVertex = theSubGraph.getNumVertex();
00145       ID *subMap = new ID(numSubVertex);
00146       localCol[j] = subMap;
00147       if (numSubVertex > maxNumSubVertex)
00148         maxNumSubVertex = numSubVertex;
00149     }
00150 
00151     size = theGraph.getNumVertex();
00152   
00153     // check we have enough space in iDiagLoc and iLastCol
00154     // if not delete old and create new
00155     if (size != Bsize) { 
00156         if (iDiagLoc != 0) delete [] iDiagLoc;
00157         iDiagLoc = new int[size];
00158 
00159         if (iDiagLoc == 0) {
00160             opserr << "WARNING DistributedProfileSPDLinSOE::setSize() : ";
00161             opserr << " - ran out of memory for iDiagLoc\n";
00162             size = 0; Asize = 0;
00163             result = -1;
00164         }
00165     }
00166 
00167     // zero out iDiagLoc 
00168     for (int i=0; i<size; i++) {
00169         iDiagLoc[i] = 0;
00170     }
00171 
00172     // now we go through the vertices to find the height of each col and
00173     // width of each row from the connectivity information.
00174     
00175     Vertex *vertexPtr;
00176     VertexIter &theVertices = theGraph.getVertices();
00177 
00178     while ((vertexPtr = theVertices()) != 0) {
00179         int vertexNum = vertexPtr->getTag();
00180         const ID &theAdjacency = vertexPtr->getAdjacency();
00181         int iiDiagLoc = iDiagLoc[vertexNum];
00182         int *iiDiagLocPtr = &(iDiagLoc[vertexNum]);
00183 
00184         for (int i=0; i<theAdjacency.Size(); i++) {
00185             int otherNum = theAdjacency(i);
00186             int diff = vertexNum-otherNum;
00187             if (diff > 0) {
00188                 if (iiDiagLoc < diff) {
00189                     iiDiagLoc = diff;
00190                     *iiDiagLocPtr = diff;
00191                 }
00192             } 
00193         }
00194     }
00195 
00196 
00197     // now go through iDiagLoc, adding 1 for the diagonal element
00198     // and then adding previous entry to give current location.
00199     if (iDiagLoc != 0)
00200         iDiagLoc[0] = 1; // NOTE FORTRAN ARRAY LOCATION - 1 of solvers uses library
00201 
00202     for (int j=1; j<size; j++)
00203         iDiagLoc[j] = iDiagLoc[j] + 1 + iDiagLoc[j-1];
00204 
00205     static ID data(1);
00206     data(0) = size;
00207 
00208     ID iLoc(iDiagLoc, size);
00209 
00210     // to each distributed soe send the size data
00211     // and merge them into master graph
00212 
00213     for (int j=0; j<numChannels; j++) {
00214       Channel *theChannel = theChannels[j];
00215       theChannel->sendID(0, 0, data);
00216       theChannel->sendID(0, 0, iLoc);
00217 
00218 
00219       static ID remoteLocalSize(1);
00220       ID *subMap = localCol[j];
00221       theChannel->recvID(0, 0, *subMap);
00222       theChannel->recvID(0, 0, remoteLocalSize);
00223       (*sizeLocal)(j) = remoteLocalSize(0);
00224     }    
00225 
00226     myProfileSize = iDiagLoc[size-1];
00227   }
00228 
00229   profileSize = myProfileSize;
00230   int numCols = theGraph.getNumVertex();
00231 
00232   if (processID != 0) {
00233     ID &globalMap = *(localCol[0]);
00234     ID *localMap = new ID(size);
00235   
00236     localMap->Zero();
00237     for (int k=0; k< globalMap.Size(); k++)
00238       (*localMap)(globalMap(k)) = k; 
00239     delete localCol[0];
00240     localCol[0] = localMap;
00241   }
00242 
00243 
00244   // check if we need more space to hold A
00245   // if so then go get it
00246   if (profileSize != Asize) { 
00247 
00248     // create some space for storing data sent from processes
00249     if (processID == 0) {
00250       if (workArea != 0)
00251         delete [] workArea;
00252 
00253       workArea = new double [profileSize];
00254       sizeWork = profileSize;
00255     }
00256     
00257     // delete old space
00258     if (A != 0)
00259       delete [] A;
00260     
00261     // get new space
00262     A = new double[profileSize];
00263     
00264     if (A == 0) {
00265       opserr << "DistributedProfileSPDLinSOE::ProfileSPDLinSOE :";
00266       opserr << " ran out of memory for A (size,Profile) (";
00267       opserr << size <<", " << profileSize << ") \n";
00268       size = 0;  Asize = 0;  profileSize = 0;
00269       result = -1;
00270     }
00271     else 
00272       Asize = profileSize;
00273   }
00274   
00275   // zero the matrix
00276   for (int k=0; k<profileSize; k++)
00277     A[k] = 0;
00278   
00279   isAfactored = false;
00280   isAcondensed = false;    
00281   
00282   if (size > Bsize) { // we have to get another space for A
00283     
00284     // delete the old
00285     if (B != 0) delete [] B;
00286     if (X != 0) delete [] X;
00287     if (myB != 0) delete [] myB;
00288     
00289     // create the new   
00290     B = new double[size];
00291     X = new double[size];
00292     myB = new double[size];
00293 
00294     if (B == 0 || X == 0 || myB == 0) {
00295       opserr << "DistributedProfileSPDLinSOE::ProfileSPDLinSOE :";
00296       opserr << " ran out of memory for vectors (size) (";
00297       opserr << size << ") \n";
00298       size = 0; Bsize = 0;
00299       result = -1;
00300     }
00301   }
00302   
00303   // zero the vectors
00304   for (int l=0; l<size; l++) {
00305     B[l] = 0;
00306     X[l] = 0;
00307     myB[l] = 0;
00308 
00309   }
00310   
00311   if (size != oldSize) {
00312     
00313     if (vectX != 0)
00314       delete vectX;
00315 
00316     if (vectB != 0)
00317       delete vectB;
00318 
00319     if (myVectB != 0)
00320       delete myVectB;
00321     
00322     if (myVectB != 0)
00323       delete myVectB;
00324 
00325     vectX = new Vector(X,size);
00326     vectB = new Vector(B,size);
00327     myVectB = new Vector(myB, size);
00328     
00329     if (size > Bsize)
00330       Bsize = size;
00331   }
00332   
00333   // invoke setSize() on the Solver
00334   LinearSOESolver *the_Solver = this->getSolver();
00335   int solverOK = the_Solver->setSize();
00336   if (solverOK < 0) {
00337     opserr << "WARNING DistributedProfileSPDLinSOE::setSize :";
00338     opserr << " solver failed setSize()\n";
00339     return solverOK;
00340   }    
00341 
00342   return result;    
00343 }
00344 
00345 
00346 int 
00347 DistributedProfileSPDLinSOE::addA(const Matrix &m, const ID &id, double fact)
00348 {
00349   // check for a quick return 
00350   if (fact == 0.0)  return 0;
00351   
00352   // check that m and id are of similar size
00353   int idSize = id.Size();    
00354   if (idSize != m.noRows() && idSize != m.noCols()) {
00355     opserr << "DistributedProfileSPDLinSOE::addA()      - Matrix and ID not of similar sizes\n";
00356     return -1;
00357   }
00358 
00359   ID *theMap = 0;
00360   if (numChannels > 0) 
00361     theMap = localCol[0];
00362   
00363   if (fact == 1.0) { // do not need to multiply 
00364     for (int i=0; i<idSize; i++) {
00365       int col = id(i);
00366       if (col < size && col >= 0) {
00367         //      double *coliiPtr = &A[iDiagLoc[col] -1]; // -1 as fortran indexing 
00368         double *coliiPtr;
00369         if (processID == 0)
00370           coliiPtr = &A[iDiagLoc[col] -1]; // -1 as fortran indexing 
00371         else
00372           coliiPtr = &A[iDiagLoc[(*theMap)(col)] -1];
00373 
00374         for (int j=0; j<idSize; j++) {
00375           int row = id(j);
00376           if (row <size && row >= 0 && 
00377               row <= col) { 
00378             
00379             // we only add upper and inside profile
00380             double *APtr = coliiPtr + (row-col);
00381             *APtr += m(j,i);
00382           }
00383         }  // for j
00384       } 
00385     }  // for i
00386   } else {
00387     for (int i=0; i<idSize; i++) {
00388       int col = id(i);
00389       if (col < size && col >= 0) {
00390         //  ydouble *coliiPtr = &A[iDiagLoc[col] -1]; // -1 as fortran indexing                 
00391         double *coliiPtr;
00392         if (processID == 0)
00393           coliiPtr = &A[iDiagLoc[col] -1]; // -1 as fortran indexing 
00394         else
00395           coliiPtr = &A[iDiagLoc[(*theMap)(col)] -1];
00396                         
00397         for (int j=0; j<idSize; j++) {
00398           int row = id(j);
00399           if (row <size && row >= 0 && 
00400               row <= col) { 
00401             
00402             // we only add upper and inside profile
00403             double *APtr = coliiPtr + (row-col);
00404             *APtr += m(j,i) * fact;
00405           }
00406         }  // for j
00407       } 
00408     }  // for i
00409     
00410   }
00411   return 0;
00412 }
00413 
00414 int 
00415 DistributedProfileSPDLinSOE::solve(void)
00416 {
00417   static ID result(1);
00418 
00419   //
00420   // if subprocess send B and A and receive back result X, B & result
00421   //
00422 
00423   if (processID != 0) {
00424     Channel *theChannel = theChannels[0];
00425 
00426     // send B
00427     theChannel->sendVector(0, 0, *myVectB);
00428 
00429     if (isAfactored == false) {
00430       // send A in packets placed in vector X
00431       Vector vectA(A, (*sizeLocal)(0));    
00432       theChannel->sendVector(0, 0, vectA);
00433     }
00434     // receive X,B and result
00435     theChannel->recvVector(0, 0, *vectX);
00436     theChannel->recvVector(0, 0, *vectB);
00437     theChannel->recvID(0, 0, result);
00438     isAfactored = true;
00439   } 
00440 
00441   //
00442   // if main process, recv B & A from all, solve and send back X, B & result
00443   //
00444 
00445   else {
00446     
00447     // add P0 contribution to B
00448     *vectB = *myVectB;
00449     
00450     // receive X and A contribution from subprocess & add them in
00451     for (int j=0; j<numChannels; j++) {
00452 
00453       // get X & add
00454       Channel *theChannel = theChannels[j];
00455       theChannel->recvVector(0, 0, *vectX);
00456       *vectB += *vectX;
00457 
00458       // get A & add using local map
00459       if (isAfactored == false) {
00460         const ID &localMap = *(localCol[j]);
00461         int localSize = (*sizeLocal)(j);
00462         Vector vectA(workArea, localSize);    
00463         theChannel->recvVector(0, 0, vectA);
00464         
00465         int loc = 0;
00466         for (int i=0; i<localMap.Size(); i++) {
00467           int col = localMap(i);
00468           int colSize, pos;
00469           
00470           if (col == 0) {
00471             colSize = 1;
00472             pos = 0;
00473           }
00474           else {
00475             pos = iDiagLoc[col-1];
00476             colSize = iDiagLoc[col] - iDiagLoc[col-1];
00477           }
00478           for (int k=0; k<colSize; k++) {
00479             A[pos++] += workArea[loc++];
00480           }
00481         }
00482       }    
00483     }
00484 
00485     //  opserr << *vectB;
00486 
00487     // solve
00488     result(0) = this->LinearSOE::solve();
00489 
00490     //    opserr << *vectX;
00491 
00492     // send results back
00493     for (int j=0; j<numChannels; j++) {
00494       Channel *theChannel = theChannels[j];
00495       theChannel->sendVector(0, 0, *vectX);
00496       theChannel->sendVector(0, 0, *vectB);
00497       theChannel->sendID(0, 0, result);      
00498     }
00499   } 
00500 
00501   return result(0);
00502 }       
00503 
00504 
00505 int 
00506 DistributedProfileSPDLinSOE::addB(const Vector &v, const ID &id, double fact)
00507 {
00508     
00509     // check for a quick return 
00510     if (fact == 0.0)  return 0;
00511 
00512     // check that m and id are of similar size
00513     int idSize = id.Size();        
00514     if (idSize != v.Size() ) {
00515         opserr << "DistributedProfileSPDLinSOE::addB() -";
00516         opserr << " Vector and ID not of similar sizes\n";
00517         return -1;
00518     }    
00519     
00520     if (fact == 1.0) { // do not need to multiply if fact == 1.0
00521         for (int i=0; i<id.Size(); i++) {
00522             int pos = id(i);
00523             if (pos <size && pos >= 0)
00524                 myB[pos] += v(i);
00525         }
00526     } else if (fact == -1.0) { // do not need to multiply if fact == -1.0
00527         for (int i=0; i<id.Size(); i++) {
00528             int pos = id(i);
00529             if (pos <size && pos >= 0)
00530                 myB[pos] -= v(i);
00531         }
00532     } else {
00533         for (int i=0; i<id.Size(); i++) {
00534             int pos = id(i);
00535             if (pos <size && pos >= 0)
00536                 myB[pos] += v(i) * fact;
00537         }
00538     }   
00539     return 0;
00540 }
00541 
00542 int
00543 DistributedProfileSPDLinSOE::setB(const Vector &v, double fact)
00544 {
00545     // check for a quick return 
00546     if (fact == 0.0)  return 0;
00547 
00548 
00549     if (v.Size() != size) {
00550         opserr << "WARNING DistributedBandGenLinSOE::setB() -";
00551         opserr << " incomptable sizes " << size << " and " << v.Size() << endln;
00552         return -1;
00553     }
00554     
00555     if (fact == 1.0) { // do not need to multiply if fact == 1.0
00556         for (int i=0; i<size; i++) {
00557             myB[i] = v(i);
00558         }
00559     } else if (fact == -1.0) {
00560         for (int i=0; i<size; i++) {
00561             myB[i] = -v(i);
00562         }
00563     } else {
00564         for (int i=0; i<size; i++) {
00565             myB[i] = v(i) * fact;
00566         }
00567     }   
00568     return 0;
00569 }
00570 
00571 void
00572 DistributedProfileSPDLinSOE::zeroB(void)
00573 {
00574   double *Bptr = myB;
00575   for (int i=0; i<size; i++)
00576     *Bptr++ = 0;
00577 }
00578 
00579 
00580 const Vector &
00581 DistributedProfileSPDLinSOE::getB(void)
00582 {
00583 
00584   if (processID != 0) {
00585     Channel *theChannel = theChannels[0];
00586 
00587     // send B & recv merged B
00588     theChannel->sendVector(0, 0, *myVectB);
00589     theChannel->recvVector(0, 0, *vectB);
00590   } 
00591 
00592   //
00593   // if main process, recv B & A from all, solve and send back X, B & result
00594   //
00595 
00596   else {
00597 
00598     // receive X and A contribution from subprocess & add them in
00599 
00600     *vectB = *myVectB;
00601     Vector remoteB(workArea, size);    
00602 
00603     for (int j=0; j<numChannels; j++) {
00604 
00605       Channel *theChannel = theChannels[j];
00606       theChannel->recvVector(0, 0, remoteB);
00607       *vectB += remoteB;
00608     }
00609   
00610     // send results back
00611     for (int j=0; j<numChannels; j++) {
00612       Channel *theChannel = theChannels[j];
00613       theChannel->sendVector(0, 0, *vectB);
00614     }
00615   } 
00616 
00617   return *vectB;
00618 }       
00619 
00620   
00621 int 
00622 DistributedProfileSPDLinSOE::sendSelf(int commitTag, Channel &theChannel)
00623 {
00624   int sendID =0;
00625 
00626   // if P0 check if already sent. If already sent use old processID; if not allocate a new process 
00627   // id for remote part of object, enlarge channel * to hold a channel * for this remote object.
00628 
00629   // if not P0, send current processID
00630 
00631   if (processID == 0) {
00632 
00633     // check if already using this object
00634     bool found = false;
00635     for (int i=0; i<numChannels; i++)
00636       if (theChannels[i] == &theChannel) {
00637         sendID = i+1;
00638         found = true;
00639       }
00640 
00641     // if new object, enlarge Channel pointers to hold new channel * & allocate new ID
00642     if (found == false) {
00643       int nextNumChannels = numChannels + 1;
00644       Channel **nextChannels = new Channel *[nextNumChannels];
00645       if (nextNumChannels == 0) {
00646         opserr << "DistributedProfileSPDLinSOE::sendSelf() - failed to allocate channel array of size: " << 
00647           nextNumChannels << endln;
00648         return -1;
00649       }
00650       for (int i=0; i<numChannels; i++)
00651         nextChannels[i] = theChannels[i];
00652       nextChannels[numChannels] = &theChannel;
00653       
00654       numChannels = nextNumChannels;
00655       
00656       if (theChannels != 0)
00657         delete [] theChannels;
00658       
00659       theChannels = nextChannels;
00660       
00661       if (localCol != 0)
00662         delete [] localCol;
00663       localCol = new ID *[numChannels];
00664       if (localCol == 0) {
00665         opserr << "DistributedProfileSPDLinSOE::sendSelf() - failed to allocate id array of size: " << 
00666           nextNumChannels << endln;
00667         return -1;
00668       }
00669       for (int i=0; i<numChannels; i++)
00670         localCol[i] = 0;    
00671 
00672       if (sizeLocal != 0)
00673         delete sizeLocal;
00674       
00675       sizeLocal = new ID(numChannels);
00676 
00677       // allocate new processID for remote object
00678       sendID = numChannels;
00679     }
00680 
00681   } else 
00682     sendID = processID;
00683 
00684 
00685   // send remotes processID
00686   ID idData(1);
00687   idData(0) = sendID;
00688   
00689   int res = theChannel.sendID(0, commitTag, idData);
00690   if (res < 0) {
00691     opserr <<"WARNING DistributedProfileSPDLinSOE::sendSelf() - failed to send data\n";
00692     return -1;
00693   }
00694   
00695   return 0;
00696 }
00697 
00698 
00699 int 
00700 DistributedProfileSPDLinSOE::recvSelf(int commitTag, Channel &theChannel, FEM_ObjectBroker &theBroker)
00701 {
00702 
00703   ID idData(1);
00704   int res = theChannel.recvID(0, commitTag, idData);
00705   if (res < 0) {
00706     opserr <<"WARNING DistributedProfileSPDLinSOE::recvSelf() - failed to send data\n";
00707     return -1;
00708   }           
00709   processID = idData(0);
00710 
00711   numChannels = 1;
00712   theChannels = new Channel *[1];
00713   theChannels[0] = &theChannel;
00714 
00715   localCol = new ID *[numChannels];
00716   for (int i=0; i<numChannels; i++)
00717     localCol[i] = 0;
00718 
00719   if (sizeLocal != 0)
00720     delete sizeLocal;
00721 
00722   sizeLocal = new ID(numChannels);
00723 
00724   return 0;
00725 }
00726 
00727 
00728 int
00729 DistributedProfileSPDLinSOE::setProcessID(int dTag) 
00730 {
00731   processID = dTag;
00732   return 0;
00733 }
00734 
00735 int
00736 DistributedProfileSPDLinSOE::setChannels(int nChannels, Channel **theC)
00737 {
00738   numChannels = nChannels;
00739 
00740   if (theChannels != 0)
00741     delete [] theChannels;
00742 
00743   theChannels = new Channel *[numChannels];
00744   for (int i=0; i<numChannels; i++)
00745     theChannels[i] = theC[i];
00746 
00747   localCol = new ID *[numChannels];
00748   for (int i=0; i<numChannels; i++)
00749     localCol[i] = 0;
00750 
00751 
00752   if (sizeLocal != 0)
00753     delete sizeLocal;
00754 
00755   sizeLocal = new ID(numChannels);
00756 
00757   return 0;
00758 }

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