Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

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