DOF_Numberer.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.5 $
00022 // $Date: 2005/11/28 21:28:17 $
00023 // $Source: /usr/local/cvs/OpenSees/SRC/analysis/numberer/DOF_Numberer.cpp,v $
00024                                                                         
00025                                                                         
00026 // Written: fmk 
00027 // Created: 9/96
00028 // Revision: A
00029 //
00030 // Description: This file contains the class implementation for DOF_Numberer.
00031 // DOF_Numberer is an abstract base class, i.e. no objects of it's
00032 // type can be created. 
00033 //
00034 // What: "@(#) DOF_Numberer.h, revA"
00035 
00036 #include <DOF_Numberer.h>
00037 #include <AnalysisModel.h>
00038 #include <GraphNumberer.h>
00039 #include <ID.h>
00040 #include <DOF_Group.h>
00041 #include <FE_Element.h>
00042 #include <FE_EleIter.h>
00043 #include <Channel.h>
00044 #include <Channel.h>
00045 #include <FEM_ObjectBroker.h>
00046 #include <Channel.h>
00047 #include <FEM_ObjectBroker.h>
00048 
00049 #include <Graph.h>
00050 
00051 #include <Domain.h>
00052 #include <MP_Constraint.h>
00053 #include <Node.h>
00054 #include <MP_ConstraintIter.h>
00055 #include <DOF_GrpIter.h>
00056 // Constructor
00057 
00058 DOF_Numberer::DOF_Numberer(int clsTag) 
00059 :MovableObject(clsTag),
00060  theAnalysisModel(0), theGraphNumberer(0)
00061 {
00062 
00063 }
00064 
00065 DOF_Numberer::DOF_Numberer(GraphNumberer &aGraphNumberer)
00066 :MovableObject(NUMBERER_TAG_DOF_Numberer),
00067  theAnalysisModel(0), theGraphNumberer(&aGraphNumberer)
00068 {
00069 
00070 }    
00071 
00072 DOF_Numberer::DOF_Numberer()
00073 :MovableObject(NUMBERER_TAG_DOF_Numberer),
00074  theAnalysisModel(0), theGraphNumberer(0)
00075 {
00076 
00077 }    
00078 
00079 // Destructor
00080 
00081 DOF_Numberer::~DOF_Numberer() 
00082 {
00083   if (theGraphNumberer != 0)
00084     delete theGraphNumberer;
00085 }
00086 
00087 
00088 // void setLinks(AnalysisModel &theModel)
00089 //      Method to set theAnalysisModel pointer to be address of theModel
00090 
00091 void
00092 DOF_Numberer::setLinks(AnalysisModel &theModel)
00093 {
00094     theAnalysisModel = &theModel;
00095 }
00096 
00097 
00098 
00099 int 
00100 DOF_Numberer::numberDOF(int lastDOF_Group) 
00101 {
00102     // check we have a model and a numberer
00103     Domain *theDomain = 0;
00104     if (theAnalysisModel != 0) theDomain = theAnalysisModel->getDomainPtr();
00105     if ((theAnalysisModel == 0) || (theDomain == 0)) {
00106         opserr << "WARNING DOF_Numberer::numberDOF - ";
00107         opserr << "Pointers are not set\n";
00108         return -1;
00109     }
00110     
00111     if ((theGraphNumberer == 0)) {
00112         opserr << "WARNING DOF_Numberer::numberDOF - ";
00113         opserr << "subclasses must provide own implementation\n";
00114         return -2;
00115     }    
00116 
00117     // check we cant do quick return
00118     
00119     if (theAnalysisModel->getNumDOF_Groups() == 0)
00120         return 0;
00121 
00122     // we first number the dofs using the dof group graph
00123 
00124     const ID &orderedRefs = theGraphNumberer->
00125         number(theAnalysisModel->getDOFGroupGraph(), lastDOF_Group);     
00126 
00127     // we now iterate through the DOFs first time setting -2 values
00128 
00129     int eqnNumber = 0;
00130     
00131     if (orderedRefs.Size() != theAnalysisModel->getNumDOF_Groups()) {
00132         opserr << "WARNING DOF_Numberer::numberDOF - ";
00133         opserr << "Incompatable Sizes\n";
00134         return -3;
00135     }
00136     int result = 0;
00137     
00138     int size = orderedRefs.Size();
00139     for (int i=0; i<size; i++) {
00140         int dofTag = orderedRefs(i);
00141         DOF_Group *dofPtr;      
00142         dofPtr = theAnalysisModel->getDOF_GroupPtr(dofTag);
00143         if (dofPtr == 0) {
00144             opserr << "WARNING DOF_Numberer::numberDOF - ";
00145             opserr << "DOF_Group " << dofTag << "not in AnalysisModel!\n";
00146             result = -4;
00147         } else {
00148             const ID &theID = dofPtr->getID();
00149             int idSize = theID.Size();
00150             for (int j=0; j<idSize; j++)
00151                 if (theID(j) == -2) dofPtr->setID(j,eqnNumber++);
00152         }
00153     }
00154 
00155     // iterate throgh  the DOFs second time setting -3 values
00156     for (int k=0; k<size; k++) {
00157         int dofTag = orderedRefs(k);
00158         DOF_Group *dofPtr;      
00159         dofPtr = theAnalysisModel->getDOF_GroupPtr(dofTag);
00160         if (dofPtr != 0) {
00161             const ID &theID = dofPtr->getID();
00162             int idSize = theID.Size();
00163             for (int j=0; j<idSize; j++)
00164                 if (theID(j) == -3) dofPtr->setID(j,eqnNumber++);
00165         }
00166     }
00167 
00168 
00169     // iterate through the DOFs one last time setting any -4 values
00170     // iterate throgh  the DOFs second time setting -3 values
00171     DOF_GrpIter &tDOFs = theAnalysisModel->getDOFs();
00172     DOF_Group *dofPtr;
00173     while ((dofPtr = tDOFs()) != 0) {
00174         const ID &theID = dofPtr->getID();
00175         int have4s = 0;
00176         for (int i=0; i<theID.Size(); i++)
00177             if (theID(i) == -4) have4s = 1;
00178 
00179         if (have4s == 1) {
00180                 int nodeID = dofPtr->getNodeTag();
00181                 // loop through the MP_Constraints to see if any of the
00182                 // DOFs are constrained, note constraint matrix must be diagonal
00183                 // with 1's on the diagonal
00184                 MP_ConstraintIter &theMPs = theDomain->getMPs();
00185                 MP_Constraint *mpPtr;
00186                 while ((mpPtr = theMPs()) != 0 ) {
00187                         // note keep looping over all in case multiple constraints
00188                         // are used to constrain a node -- can't assume intelli user
00189                         if (mpPtr->getNodeConstrained() == nodeID) {
00190                                 int nodeRetained = mpPtr->getNodeRetained();
00191                                 Node *nodeRetainedPtr = theDomain->getNode(nodeRetained);
00192                                 DOF_Group *retainedDOF = nodeRetainedPtr->getDOF_GroupPtr();
00193                                 const ID&retainedDOFIDs = retainedDOF->getID();
00194                                 const ID&constrainedDOFs = mpPtr->getConstrainedDOFs();
00195                                 const ID&retainedDOFs = mpPtr->getRetainedDOFs();
00196                                 for (int i=0; i<constrainedDOFs.Size(); i++) {
00197                                         int dofC = constrainedDOFs(i);
00198                                         int dofR = retainedDOFs(i);
00199                                         int dofID = retainedDOFIDs(dofR);
00200                                         dofPtr->setID(dofC, dofID);
00201                                 }
00202                         }
00203                 }               
00204         }       
00205     }
00206 
00207 
00208     int numEqn = eqnNumber;
00209 
00210     // iterate through the FE_Element getting them to set their IDs
00211     FE_EleIter &theEle = theAnalysisModel->getFEs();
00212     FE_Element *elePtr;
00213     while ((elePtr = theEle()) != 0)
00214         elePtr->setID();
00215 
00216     // set the numOfEquation in the Model
00217     theAnalysisModel->setNumEqn(numEqn);
00218 
00219     if (result == 0)
00220         return numEqn;
00221 
00222     return result;
00223 }
00224 
00225 
00226 
00227 
00228 
00229 
00230 int 
00231 DOF_Numberer::numberDOF(ID &lastDOFs) 
00232 {
00233     // check we have a model and a numberer
00234         Domain *theDomain = 0;
00235    if (theAnalysisModel != 0) theDomain = theAnalysisModel->getDomainPtr();
00236    if ((theAnalysisModel == 0) || (theDomain == 0)) {
00237         opserr << "WARNING DOF_Numberer::numberDOF - ";
00238         opserr << "Pointers are not set\n";
00239         return -1;
00240     }
00241     
00242     if ((theGraphNumberer == 0)) {
00243         opserr << "WARNING DOF_Numberer::numberDOF - ";
00244         opserr << "subclasses must provide own implementation\n";
00245         return -2;
00246     }    
00247 
00248     // check we cant do quick return
00249     if (theAnalysisModel->getNumDOF_Groups() == 0)
00250         return 0;
00251 
00252     // we first number the dofs using the dof group graph
00253         
00254     const ID &orderedRefs = theGraphNumberer->
00255         number(theAnalysisModel->getDOFGroupGraph(), lastDOFs);     
00256 
00257     // we now iterate through the DOFs first time setting -2 values
00258 
00259     int eqnNumber = 0;
00260     if (orderedRefs.Size() != theAnalysisModel->getNumDOF_Groups()) {
00261         opserr << "WARNING DOF_Numberer::numberDOF - ";
00262         opserr << "Incompatable Sizes\n";
00263         return -3;
00264     }
00265 
00266     int result =0;
00267     int size = orderedRefs.Size();
00268     for (int i=0; i<size; i++) {
00269         int dofTag = orderedRefs(i);
00270         DOF_Group *dofPtr;      
00271         dofPtr = theAnalysisModel->getDOF_GroupPtr(dofTag);
00272         if (dofPtr == 0) {
00273             opserr << "WARNING DOF_Numberer::numberDOF - ";
00274             opserr << "DOF_Group " << dofTag << "not in AnalysisModel!\n";
00275             result = -4;
00276         } else {
00277             const ID &theID = dofPtr->getID();
00278             int idSize = theID.Size();
00279             for (int j=0; j<idSize; j++)
00280                 if (theID(j) == -2) dofPtr->setID(j,eqnNumber++);
00281         }       
00282     }
00283 
00284     // iterate throgh  the DOFs first time setting -3 values
00285     
00286     for (int k=0; k<size; k++) {
00287         int dofTag = orderedRefs(k);
00288         DOF_Group *dofPtr;      
00289         dofPtr = theAnalysisModel->getDOF_GroupPtr(dofTag);
00290         if (dofPtr != 0) {
00291             const ID &theID = dofPtr->getID();
00292             int idSize = theID.Size();
00293             for (int j=0; j<idSize; j++)
00294                 if (theID(j) == -3) dofPtr->setID(j,eqnNumber++);
00295         }
00296     }
00297 
00298     // iterate through the DOFs one last time setting any -4 values
00299     // iterate throgh  the DOFs second time setting -3 values
00300     DOF_GrpIter &tDOFs = theAnalysisModel->getDOFs();
00301     DOF_Group *dofPtr;
00302     while ((dofPtr = tDOFs()) != 0) {
00303         const ID &theID = dofPtr->getID();
00304         int have4s = 0;
00305         for (int i=0; i<theID.Size(); i++)
00306             if (theID(i) == -4) have4s = 1;
00307 
00308         if (have4s == 1) {
00309                 int nodeID = dofPtr->getNodeTag();
00310                 // loop through the MP_Constraints to see if any of the
00311                 // DOFs are constrained, note constraint matrix must be diagonal
00312                 // with 1's on the diagonal
00313                 MP_ConstraintIter &theMPs = theDomain->getMPs();
00314                 MP_Constraint *mpPtr;
00315                 while ((mpPtr = theMPs()) != 0 ) {
00316                         // note keep looping over all in case multiple constraints
00317                         // are used to constrain a node -- can't assume intelli user
00318                         if (mpPtr->getNodeConstrained() == nodeID) {
00319                                 int nodeRetained = mpPtr->getNodeRetained();
00320                                 Node *nodeRetainedPtr = theDomain->getNode(nodeRetained);
00321                                 DOF_Group *retainedDOF = nodeRetainedPtr->getDOF_GroupPtr();
00322                                 const ID&retainedDOFIDs = retainedDOF->getID();
00323                                 const ID&constrainedDOFs = mpPtr->getConstrainedDOFs();
00324                                 const ID&retainedDOFs = mpPtr->getRetainedDOFs();
00325                                 for (int i=0; i<constrainedDOFs.Size(); i++) {
00326                                         int dofC = constrainedDOFs(i);
00327                                         int dofR = retainedDOFs(i);
00328                                         int dofID = retainedDOFIDs(dofR);
00329                                         dofPtr->setID(dofC, dofID);
00330                                 }
00331                         }
00332                 }               
00333         }       
00334     }
00335 
00336     int numEqn = eqnNumber;
00337 
00338     // iterate through the FE_Element getting them to set their IDs
00339     FE_EleIter &theEle = theAnalysisModel->getFEs();
00340     FE_Element *elePtr;
00341     while ((elePtr = theEle()) != 0)
00342         elePtr->setID();
00343 
00344     // set the numOfEquation in the Model
00345     theAnalysisModel->setNumEqn(numEqn);
00346     
00347     if (result == 0)
00348         return numEqn;
00349     
00350     return result;
00351 
00352 }
00353 
00354 
00355 
00356 // AnalysisModel *getAnalysisModelPtr(void)
00357 //      Method to return a pointer to theAnalysisModel for subclasses.
00358 
00359 int
00360 DOF_Numberer::sendSelf(int cTag, Channel &theChannel)
00361 {
00362     ID data(2);
00363     int dataTag = this->getDbTag();
00364 
00365     data(0) = -1;
00366     if (theGraphNumberer != 0) {
00367         data(0) = theGraphNumberer->getClassTag();
00368         data(1) = theGraphNumberer->getDbTag();
00369     }
00370     theChannel.sendID(dataTag, cTag, data);
00371     if (theGraphNumberer != 0)
00372       theGraphNumberer->sendSelf(cTag, theChannel);
00373 
00374     return 0;
00375 }
00376 
00377 int
00378 DOF_Numberer::recvSelf(int cTag, Channel &theChannel, 
00379                        FEM_ObjectBroker &theBroker)
00380 {
00381   ID data(2);
00382   int dataTag = this->getDbTag();
00383   theChannel.recvID(dataTag, cTag, data);    
00384 
00385   // get a graphNumberer
00386   if (data(0) != -1) {
00387     theGraphNumberer = theBroker.getPtrNewGraphNumberer(data(0));
00388     if (theGraphNumberer != 0) {
00389       theGraphNumberer->setDbTag(data(1));
00390       theGraphNumberer->recvSelf(cTag, theChannel,theBroker);
00391     }
00392     else {
00393       opserr << "DOF_Numberer::recvSelf() - failed to get GraphNumberer\n";
00394       return -1;
00395     }
00396   }
00397 
00398   return 0;
00399 }
00400 
00401 
00402 AnalysisModel *
00403 DOF_Numberer::getAnalysisModelPtr(void) const
00404 {
00405     return theAnalysisModel;
00406 }
00407 
00408 
00409 GraphNumberer *
00410 DOF_Numberer::getGraphNumbererPtr(void) const
00411 {
00412     return theGraphNumberer;
00413 }
00414 

Generated on Mon Oct 23 15:04:59 2006 for OpenSees by doxygen 1.5.0