SymBandEigenSOE.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.3 $
00022 // $Date: 2004/10/05 00:17:31 $
00023 // $Source: /usr/local/cvs/OpenSees/SRC/system_of_eqn/eigenSOE/SymBandEigenSOE.cpp,v $
00024 
00025 // Written: MHS
00026 // Created: Oct 2001
00027 //
00028 // Description: This file contains the class definition for
00029 // SymBandEigenSOE, which stores a symmetric banded matrix, A, for
00030 // standard eigenvalue computations.
00031 
00032 #include <SymBandEigenSOE.h>
00033 #include <SymBandEigenSolver.h>
00034 #include <Matrix.h>
00035 #include <Graph.h>
00036 #include <Vertex.h>
00037 #include <VertexIter.h>
00038 #include <f2c.h>
00039 #include <math.h>
00040 #include <Channel.h>
00041 #include <FEM_ObjectBroker.h>
00042 #include <AnalysisModel.h>
00043 
00044 SymBandEigenSOE::SymBandEigenSOE(SymBandEigenSolver &theSolvr,  
00045                                  AnalysisModel &aModel)
00046 :EigenSOE(theSolvr, EigenSOE_TAGS_SymBandEigenSOE),
00047  size(0), numSuperD(0), A(0), 
00048  Asize(0), factored(false), theModel(&aModel), M(0), Msize(0)
00049 {
00050   theSolvr.setEigenSOE(*this);
00051 }
00052 
00053 int
00054 SymBandEigenSOE::getNumEqn(void) const
00055 {
00056   return size;
00057 }
00058     
00059 SymBandEigenSOE::~SymBandEigenSOE()
00060 {
00061   if (A != 0)
00062     delete [] A;
00063   if (M != 0)
00064     delete [] M;
00065 }
00066 
00067 int 
00068 SymBandEigenSOE::setSize(Graph &theGraph)
00069 {
00070   int result = 0;
00071   size = theGraph.getNumVertex();
00072   
00073   // determine the number of superdiagonals and subdiagonals
00074   
00075   numSuperD = 0;
00076   
00077   Vertex *vertexPtr;
00078   VertexIter &theVertices = theGraph.getVertices();
00079   
00080   while ((vertexPtr = theVertices()) != 0) {
00081     int vertexNum = vertexPtr->getTag();
00082     const ID &theAdjacency = vertexPtr->getAdjacency();
00083     for (int i=0; i<theAdjacency.Size(); i++) {
00084       int otherNum = theAdjacency(i);
00085       int diff = vertexNum - otherNum;
00086       if (diff > 0) {
00087         if (diff > numSuperD)
00088           numSuperD = diff;
00089       } else 
00090         if (diff < -numSuperD)
00091           numSuperD = -diff;
00092     }
00093   }
00094   
00095   int newSize = size*(numSuperD+1);
00096   if (newSize > Asize) { // we have to get another space for A
00097     
00098     if (A != 0) 
00099       delete [] A;
00100     
00101     A = new double[newSize];
00102     
00103     if (A == 0) {
00104       opserr << "SymBandEigenSOE::setSize() -- ran out of memory for A, size = " <<
00105         size <<  " and numSuperD = : " << numSuperD << endln;
00106                               
00107       Asize = 0; size = 0; numSuperD = 0;
00108       result= -1;
00109     }
00110     else  
00111       Asize = newSize;
00112   }
00113   
00114   // zero the matrix
00115   for (int i = 0; i < Asize; i++)
00116     A[i] = 0.0;
00117   
00118   factored = false;
00119   
00120   // invoke setSize() on the Solver
00121   EigenSolver *theSolvr = this->getSolver();
00122   int solverOK = theSolvr->setSize();
00123   if (solverOK < 0) {
00124     opserr << "SymBandEigenSOE::setSize() -- solver failed in setSize()\n";
00125                             
00126     return solverOK;
00127   } 
00128   
00129   return result;    
00130 }
00131 
00132 int 
00133 SymBandEigenSOE::addA(const Matrix &m, const ID &id, double fact)
00134 {
00135   // check for a quick return 
00136   if (fact == 0.0)
00137     return 0;
00138 
00139   // check that m and id are of similar size
00140   int idSize = id.Size();    
00141   if (idSize != m.noRows() && idSize != m.noCols()) {
00142     opserr << "SymBandEigenSOE::addA() -- Matrix and ID not of similar sizes,\n";
00143     return -1;
00144   }
00145 
00146   if (fact == 1.0) { // do not need to multiply 
00147     for (int i = 0; i < idSize; i++) {
00148       int col = id(i);
00149       if (col < size && col >= 0) {
00150         double *coliiPtr = A +(col+1)*(numSuperD+1) - 1;
00151         int minColRow = col - (numSuperD+1) + 1;
00152         for (int j = 0; j < idSize; j++) {
00153           int row = id(j);
00154           if (row <size && row >= 0 && 
00155               row <= col && row >= minColRow) { // only add upper
00156             double *APtr = coliiPtr + (row-col);
00157             *APtr += m(j,i);
00158           }
00159         }  // for j
00160       } 
00161     }  // for i
00162   } else {
00163     for (int i = 0; i < idSize; i++) {
00164       int col = id(i);
00165       if (col < size && col >= 0) {
00166         double *coliiPtr = A +(col+1)*(numSuperD+1) - 1;
00167         int minColRow = col - (numSuperD+1) +1;
00168         for (int j = 0; j < idSize; j++) {
00169           int row = id(j);
00170           if (row < size && row >= 0 && 
00171               row <= col && row >= minColRow) { // only add upper
00172             double *APtr = coliiPtr + (row-col);
00173             *APtr += m(j,i)*fact;
00174           }
00175         }  // for j
00176       } 
00177     }  // for i
00178   }
00179 
00180   return 0;
00181 }
00182 
00183 void 
00184 SymBandEigenSOE::zeroA(void)
00185 {
00186   double *Aptr = A;
00187   
00188   for (int i = 0; i < Asize; i++)
00189     *Aptr++ = 0;
00190   
00191   factored = false;
00192 }
00193 
00194 int 
00195 SymBandEigenSOE::addM(const Matrix &m, const ID &id, double fact)
00196 {
00197   // check for a quick return 
00198   if (fact == 0.0)
00199     return 0;
00200 
00201   // check memory for M has been allocated
00202   if (M == 0 || Msize != size) {
00203     if (M != 0)
00204       delete [] M;
00205     M = new double[size];
00206     Msize = size;
00207     if (M == 0) {
00208       opserr << "WARNING SymBandEigenSOE::addM() - out of memory creating M for size: " << size << endln;
00209       return -1;
00210     }
00211     for (int i=0; i<size; i++)
00212       M[i] = 0.0;
00213   }
00214 
00215   // check that m and id are of similar size
00216   int idSize = id.Size();    
00217   if (idSize != m.noRows() && idSize != m.noCols()) {
00218     opserr << "WARING: SymBandEigenSOE::addM() -- Matrix and ID not of similar sizes!!\n";
00219     return -1;
00220   }
00221 
00222   for (int i = 0; i <idSize; i++) {
00223     int loc = id(i);
00224     if (loc >= 0)
00225       M[loc] += fact * m(i,i);
00226   }
00227 
00228 
00229   bool issueWarning = false;
00230   for (int ii=0; ii<idSize; ii++) 
00231     for (int jj=0; jj<idSize; jj++)
00232       if (ii!=jj)
00233         if (m(ii,jj) != 0.0)
00234           issueWarning = true;
00235   if (issueWarning == true) {
00236       opserr << "WARNING SymBandEigenSOE::addM() - m passed was not diagonal, only diagonal entries added\n";
00237   }
00238   
00239   return 0;
00240 }
00241 
00242 void 
00243 SymBandEigenSOE::zeroM(void)
00244 {
00245   if (M != 0)
00246     for (int i=0; i<size; i++)
00247       M[i] = 0.0;
00248 
00249   return;
00250 }
00251 
00252 int 
00253 SymBandEigenSOE::sendSelf(int commitTag, Channel &theChannel)
00254 {
00255   return 0;
00256 }
00257     
00258 int 
00259 SymBandEigenSOE::recvSelf(int commitTag, Channel &theChannel, 
00260                         FEM_ObjectBroker &theBroker)
00261 {
00262   return 0;
00263 }

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