AnalysisModel.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.14 $
00022 // $Date: 2006/03/29 18:50:37 $
00023 // $Source: /usr/local/cvs/OpenSees/SRC/analysis/model/AnalysisModel.cpp,v $
00024                                                                         
00025                                                                         
00026 // Written: fmk 
00027 // Created: Fri Sep 20 15:27:47: 1996
00028 // Revision: A
00029 //
00030 // Purpose: This file contains the class definition for AnalysisModel
00031 // AnalysisModel is a container class. The class is responsible for holding
00032 // and providing access to the Elements, Nodes, LoadCases, SP_Constraints 
00033 // and MP_Constraints. These objects are all added to the AnalysisModel by a 
00034 // ModelBuilder.
00035 //
00036 // What: "@(#) AnalysisModel.C, revA"
00037 
00038 #include <stdlib.h>
00039 
00040 #include <ArrayOfTaggedObjects.h>
00041 #include <AnalysisModel.h>
00042 #include <Domain.h>
00043 #include <FE_Element.h>
00044 #include <DOF_Group.h>
00045 #include <DOF_GrpIter.h>
00046 #include <FE_EleIter.h>
00047 #include <Graph.h>
00048 #include <Vertex.h>
00049 #include <Node.h>
00050 #include <NodeIter.h>
00051 #include <ConstraintHandler.h>
00052 
00053 
00054 #include <MapOfTaggedObjects.h>
00055 
00056 #include <Timer.h>
00057 
00058 #define START_EQN_NUM 0
00059 #define START_VERTEX_NUM 0
00060 
00061 //  AnalysisModel();
00062 //      constructor
00063 
00064 AnalysisModel::AnalysisModel(int theClassTag)
00065 :MovableObject(theClassTag),
00066  myDomain(0), myHandler(0),
00067  myDOFGraph(0), myGroupGraph(0),
00068  numFE_Ele(0), numDOF_Grp(0), numEqn(0)
00069 {
00070     theFEs     = new ArrayOfTaggedObjects(1024);
00071     theDOFs    =  new ArrayOfTaggedObjects(1024);
00072     theFEiter  = new FE_EleIter(theFEs);
00073     theDOFiter = new DOF_GrpIter(theDOFs);
00074 
00075     // for subclasses to use - they provide own container stuff
00076 } 
00077 
00078 AnalysisModel::AnalysisModel()
00079 :MovableObject(AnaMODEL_TAGS_AnalysisModel),
00080  myDomain(0), myHandler(0),
00081  myDOFGraph(0), myGroupGraph(0),
00082  numFE_Ele(0), numDOF_Grp(0), numEqn(0)
00083 {
00084   theFEs     = new ArrayOfTaggedObjects(256);
00085   theDOFs    = new ArrayOfTaggedObjects(256);
00086   theFEiter  = new FE_EleIter(theFEs);
00087   theDOFiter = new DOF_GrpIter(theDOFs);
00088 } 
00089 
00090 
00091 AnalysisModel::AnalysisModel(TaggedObjectStorage &theFes, TaggedObjectStorage &theDofs)
00092 :MovableObject(AnaMODEL_TAGS_AnalysisModel),
00093  myDomain(0), myHandler(0),
00094  myDOFGraph(0), myGroupGraph(0),
00095  numFE_Ele(0), numDOF_Grp(0), numEqn(0)
00096 {
00097   theFEs     = &theFes;
00098   theDOFs    = &theDofs;
00099   theFEiter  = new FE_EleIter(theFEs);
00100   theDOFiter = new DOF_GrpIter(theDOFs);
00101 } 
00102 
00103 
00104 // ~AnalysisModel();    
00105 AnalysisModel::~AnalysisModel()
00106 {
00107   if (theFEs != 0) {
00108     theFEs->clearAll();
00109     delete theFEs;
00110   }
00111 
00112   if (theDOFs != 0) {
00113     theDOFs->clearAll();
00114     delete theDOFs;
00115   }
00116 
00117   if (theFEiter != 0)
00118     delete theFEiter;
00119 
00120   if (theDOFiter != 0)
00121     delete theDOFiter;
00122 
00123   if (myGroupGraph != 0) {
00124     delete myGroupGraph;    
00125   }     
00126   
00127   if (myDOFGraph != 0) {
00128     delete myDOFGraph;
00129   }
00130 }    
00131 
00132 void
00133 AnalysisModel::setLinks(Domain &theDomain, ConstraintHandler &theHandler)
00134 {
00135     myDomain = &theDomain;
00136     myHandler = &theHandler;
00137 }
00138 
00139 
00140 // void addFE_Element(FE_Element *);
00141 //      Method to add an element to the model.
00142 
00143 bool
00144 AnalysisModel::addFE_Element(FE_Element *theElement)
00145 {
00146   // check we don't add a null pointer or this is a subclass
00147   // trying to use this method when it should'nt
00148   if (theElement == 0 || theFEs == 0)
00149       return false;
00150 
00151   // check if an Element with a similar tag already exists in the Domain
00152   int tag = theElement->getTag();
00153   TaggedObject *other = theFEs->getComponentPtr(tag);
00154   if (other != 0) {
00155     opserr << "AnalysisModel::addFE_Element - element with tag " << tag << "already exists in model\n"; 
00156     return false;
00157   }
00158 
00159   // add the element to the container object for the elements
00160   bool result = theFEs->addComponent(theElement);
00161   if (result == true) {
00162     theElement->setAnalysisModel(*this);
00163     numFE_Ele++;
00164     return true;  // o.k.
00165   } else
00166     return false;
00167 
00168 
00169   return result;
00170 }
00171 
00172 
00173 
00174 
00175 // void addDOF_Group(DOF_Group *);
00176 //      Method to add an element to the model.
00177 
00178 bool
00179 AnalysisModel::addDOF_Group(DOF_Group *theGroup)
00180 {
00181 
00182   // check we don't add a null pointer or this is a subclass trying
00183   // to use a method it should'nt be using
00184   if (theGroup == 0 || theDOFs == 0)
00185       return false;
00186   
00187 
00188   // check if an Element with a similar tag already exists in the Domain
00189   int tag = theGroup->getTag();
00190   TaggedObject *other = theDOFs->getComponentPtr(tag);
00191   if (other != 0) {
00192     opserr << "AnalysisModel::addDOF_Group - group with tag " << tag << "already exists in model\n"; 
00193     return false;
00194   }
00195 
00196   // add the element to the container object for the elements
00197   bool result = theDOFs->addComponent(theGroup);
00198   if (result == true) {
00199     numDOF_Grp++;
00200     return true;  // o.k.
00201   } else
00202     return false;
00203 }
00204 
00205 void
00206 AnalysisModel::clearAll(void) 
00207 {
00208     // if the graphs have been constructed delete them
00209     if (myDOFGraph != 0)
00210         delete myDOFGraph;
00211 
00212     if (myGroupGraph != 0)
00213         delete myGroupGraph;    
00214 
00215     theFEs->clearAll();
00216     theDOFs->clearAll();
00217 
00218     myDOFGraph = 0;
00219     myGroupGraph = 0;
00220     
00221     numFE_Ele =0;
00222     numDOF_Grp = 0;
00223     numEqn = 0;    
00224 }
00225 
00226 
00227 
00228 
00229 int
00230 AnalysisModel::getNumDOF_Groups(void) const
00231 {
00232   return numDOF_Grp;
00233 }
00234 
00235 
00236 DOF_Group *
00237 AnalysisModel::getDOF_GroupPtr(int tag)
00238 {
00239   TaggedObject *other = theDOFs->getComponentPtr(tag);
00240   if (other == 0) {
00241     return 0;
00242   }
00243   DOF_Group *result = (DOF_Group *)other;
00244   return result;
00245 }
00246 
00247 
00248 FE_EleIter &
00249 AnalysisModel::getFEs()
00250 {
00251     theFEiter->reset();
00252     return *theFEiter;
00253 }
00254 
00255 DOF_GrpIter &
00256 AnalysisModel::getDOFs()
00257 {
00258     theDOFiter->reset();
00259     return *theDOFiter;
00260 }
00261 
00262 void 
00263 AnalysisModel::setNumEqn(int theNumEqn)
00264 {
00265     numEqn = theNumEqn;
00266 }
00267 
00268 int 
00269 AnalysisModel::getNumEqn(void) const
00270 {
00271     return numEqn;
00272 }
00273 
00274 
00275 Graph &
00276 AnalysisModel::getDOFGraph(void)
00277 {
00278   if (myDOFGraph == 0) {
00279     int numVertex = this->getNumDOF_Groups();
00280 
00281     //    myDOFGraph = new Graph(numVertex);
00282     MapOfTaggedObjects *graphStorage = new MapOfTaggedObjects();
00283     myDOFGraph = new Graph(*graphStorage);
00284 
00285     //
00286     // create a vertex for each dof
00287     //
00288     
00289     DOF_Group *dofPtr =0;
00290     DOF_GrpIter &theDOFs = this->getDOFs();
00291     while ((dofPtr = theDOFs()) != 0) {
00292       const ID &id = dofPtr->getID();
00293       int size = id.Size();
00294       for (int i=0; i<size; i++) {
00295         int dofTag = id(i);
00296         if (dofTag >= START_EQN_NUM) {
00297           Vertex *vertexPtr = myDOFGraph->getVertexPtr(dofTag);
00298           if (vertexPtr == 0) {
00299             Vertex *vertexPtr = new Vertex(dofTag, dofTag);      
00300             if (vertexPtr == 0) {
00301               opserr << "WARNING AnalysisModel::getDOFGraph";
00302               opserr << " - Not Enough Memory to create " << i+1 << "th Vertex\n";
00303               return *myDOFGraph;
00304             }
00305             if (myDOFGraph->addVertex(vertexPtr, false) == false) {
00306               opserr << "WARNING AnalysisModel::getDOFGraph - error adding vertex\n";
00307               return *myDOFGraph;
00308             }
00309           }
00310         }
00311       }
00312     }
00313     
00314     // now add the edges, by looping over the FE_elements, getting their
00315     // IDs and adding edges between DOFs for equation numbers >= START_EQN_NUM
00316     
00317     FE_Element *elePtr =0;
00318     FE_EleIter &eleIter = this->getFEs();
00319     int cnt = 0;
00320     
00321     while((elePtr = eleIter()) != 0) {
00322       const ID &id = elePtr->getID();
00323       cnt++;
00324       int size = id.Size();
00325       for (int i=0; i<size; i++) {
00326         int eqn1 = id(i);
00327         
00328         // if eqnNum of DOF is a valid eqn number add an edge
00329         // to all other DOFs with valid eqn numbers.
00330         
00331         if (eqn1 >=START_EQN_NUM) {
00332           for (int j=i+1; j<size; j++) {
00333             int eqn2 = id(j);
00334             if (eqn2 >=START_EQN_NUM)
00335               myDOFGraph->addEdge(eqn1-START_EQN_NUM+START_VERTEX_NUM,
00336                                   eqn2-START_EQN_NUM+START_VERTEX_NUM);
00337           }
00338         }
00339       }
00340     }
00341   }    
00342 
00343   return *myDOFGraph;
00344 }
00345 
00346 
00347 Graph &
00348 AnalysisModel::getDOFGroupGraph(void)
00349 {
00350   if (myGroupGraph == 0) {
00351     int numVertex = this->getNumDOF_Groups();
00352 
00353     if (numVertex == 0) {
00354         opserr << "WARNING AnalysisMode::getGroupGraph";
00355         opserr << "  - 0 vertices, has the Domain been populated?\n";
00356         exit(-1);
00357     }   
00358 
00359     //    myGroupGraph = new Graph(numVertex);
00360     MapOfTaggedObjects *graphStorage = new MapOfTaggedObjects();
00361     myGroupGraph = new Graph(*graphStorage);
00362 
00363     if (numVertex == 0) {
00364         opserr << "WARNING AnalysisMode::getGroupGraph";
00365         opserr << "  - out of memory\n";
00366         exit(-1);
00367     }   
00368         
00369     DOF_Group *dofPtr;
00370 
00371     // now create the vertices with a reference equal to the DOF_Group number.
00372     // and a tag which ranges from 0 through numVertex-1
00373 
00374     DOF_GrpIter &dofIter2 = this->getDOFs();
00375     int count = START_VERTEX_NUM;
00376     while ((dofPtr = dofIter2()) != 0) {
00377         int DOF_GroupTag = dofPtr->getTag();
00378         int DOF_GroupNodeTag = dofPtr->getNodeTag();
00379         int numDOF = dofPtr->getNumFreeDOF();
00380         Vertex *vertexPtr = new Vertex(DOF_GroupTag, DOF_GroupNodeTag, 0, numDOF);
00381 
00382         if (vertexPtr == 0) {
00383             opserr << "WARNING DOF_GroupGraph::DOF_GroupGraph";
00384             opserr << " - Not Enough Memory to create ";
00385             opserr << count << "th Vertex\n";
00386             return *myGroupGraph;
00387         }
00388         
00389         myGroupGraph->addVertex(vertexPtr);
00390     }
00391 
00392     // now add the edges, by looping over the Elements, getting their
00393     // IDs and adding edges between DOFs for equation numbers >= START_EQN_NUM
00394     
00395     FE_Element *elePtr;
00396     FE_EleIter &eleIter = this->getFEs();
00397 
00398     while((elePtr = eleIter()) != 0) {
00399         const ID &id = elePtr->getDOFtags();
00400         int size = id.Size();
00401         for (int i=0; i<size; i++) {
00402             int dof1 = id(i);
00403             for (int j=0; j<size; j++) 
00404                 if (i != j) {
00405                     int dof2 = id(j);
00406                     myGroupGraph->addEdge(dof1,dof2);
00407                 }
00408         }
00409     }
00410   }
00411 
00412   return *myGroupGraph;
00413 }
00414 
00415 
00416 
00417 
00418 void 
00419 AnalysisModel::setResponse(const Vector &disp,
00420                            const Vector &vel, 
00421                            const Vector &accel)
00422 {
00423     DOF_GrpIter &theDOFGrps = this->getDOFs();
00424     DOF_Group   *dofPtr;
00425 
00426     while ((dofPtr = theDOFGrps()) != 0) {
00427         dofPtr->setNodeDisp(disp);
00428         dofPtr->setNodeVel(vel);
00429         dofPtr->setNodeAccel(accel);    
00430     }
00431 }       
00432         
00433 void 
00434 AnalysisModel::setDisp(const Vector &disp)
00435 {
00436     DOF_GrpIter &theDOFGrps = this->getDOFs();
00437     DOF_Group   *dofPtr;
00438 
00439     while ((dofPtr = theDOFGrps()) != 0) 
00440         dofPtr->setNodeDisp(disp);
00441 }       
00442         
00443 void 
00444 AnalysisModel::setVel(const Vector &vel)
00445 {
00446         DOF_GrpIter &theDOFGrps = this->getDOFs();
00447     DOF_Group   *dofPtr;
00448     
00449     while ((dofPtr = theDOFGrps()) != 0) 
00450         dofPtr->setNodeVel(vel);
00451 }       
00452         
00453 
00454 void 
00455 AnalysisModel::setAccel(const Vector &accel)
00456 {
00457     DOF_GrpIter &theDOFGrps = this->getDOFs();
00458     DOF_Group   *dofPtr;
00459     
00460     while ((dofPtr = theDOFGrps()) != 0) 
00461         dofPtr->setNodeAccel(accel);    
00462 }       
00463 
00464 void 
00465 AnalysisModel::incrDisp(const Vector &disp)
00466 {
00467     DOF_GrpIter &theDOFGrps = this->getDOFs();
00468     DOF_Group   *dofPtr;
00469 
00470     while ((dofPtr = theDOFGrps()) != 0) 
00471         dofPtr->incrNodeDisp(disp);
00472 }       
00473         
00474 void 
00475 AnalysisModel::incrVel(const Vector &vel)
00476 {
00477         DOF_GrpIter &theDOFGrps = this->getDOFs();
00478     DOF_Group   *dofPtr;
00479     
00480     while ((dofPtr = theDOFGrps()) != 0) 
00481         dofPtr->incrNodeVel(vel);
00482 }       
00483         
00484 void 
00485 AnalysisModel::incrAccel(const Vector &accel)
00486 {
00487     DOF_GrpIter &theDOFGrps = this->getDOFs();
00488     DOF_Group   *dofPtr;
00489     
00490     while ((dofPtr = theDOFGrps()) != 0) 
00491         dofPtr->incrNodeAccel(accel);   
00492 }       
00493 
00494 
00495 void 
00496 AnalysisModel::setNumEigenvectors(int numEigenvectors)
00497 {
00498     Node *theNode;
00499     NodeIter &theNodes = myDomain->getNodes();
00500     while ((theNode = theNodes()) != 0)
00501         theNode->setNumEigenvectors(numEigenvectors);
00502 }       
00503 
00504 void 
00505 AnalysisModel::setEigenvalues(const Vector &eigenvalues)
00506 {
00507     myDomain->setEigenvalues(eigenvalues);
00508 }       
00509 
00510 void 
00511 AnalysisModel::setEigenvector(int mode, const Vector &eigenvalue)
00512 {
00513     DOF_GrpIter &theDOFGrps = this->getDOFs();
00514     DOF_Group   *dofPtr;
00515     
00516     while ((dofPtr = theDOFGrps()) != 0) 
00517         dofPtr->setEigenvector(mode, eigenvalue);       
00518 }       
00519 
00520 void 
00521 AnalysisModel::applyLoadDomain(double pseudoTime)
00522 {
00523     // check to see there is a Domain linked to the Model
00524 
00525     if (myDomain == 0) {
00526         opserr << "WARNING: AnalysisModel::applyLoadDomain. No Domain linked.\n";
00527         return;
00528     }
00529 
00530     // invoke the method
00531     myDomain->applyLoad(pseudoTime);
00532     myHandler->applyLoad();
00533 }
00534 
00535 
00536 int
00537 AnalysisModel::updateDomain(void)
00538 {
00539     // check to see there is a Domain linked to the Model
00540 
00541     if (myDomain == 0) {
00542         opserr << "WARNING: AnalysisModel::updateDomain. No Domain linked.\n";
00543         return -1;
00544     }
00545 
00546     // invoke the method
00547     int res = myDomain->update();
00548     if (res == 0)
00549       return myHandler->update();
00550 
00551     return res;
00552 }
00553 
00554 
00555 int
00556 AnalysisModel::updateDomain(double newTime, double dT)
00557 {
00558     // check to see there is a Domain linked to the Model
00559 
00560     if (myDomain == 0) {
00561         opserr << "WARNING: AnalysisModel::updateDomain. No Domain linked.\n";
00562         return -1;
00563     }
00564 
00565     // invoke the method
00566 
00567     int res = 0;
00568     myDomain->applyLoad(newTime);
00569     if (res == 0)
00570       res = myHandler->applyLoad();
00571     if (res == 0)
00572       res = myDomain->update();
00573     if (res == 0)
00574       res = myHandler->update();
00575 
00576     return res;
00577 }
00578 
00579 
00580 int
00581 AnalysisModel::newStepDomain(double dT)
00582 {
00583     // check to see there is a Domain linked to the Model
00584 
00585     if (myDomain == 0) {
00586         opserr << "WARNING: AnalysisModel::newStep. No Domain linked.\n";
00587         return -1;
00588     }
00589 
00590     // invoke the method
00591     return myDomain->newStep(dT);
00592 
00593 }
00594 
00595 
00596 
00597 int
00598 AnalysisModel::commitDomain(void)
00599 {
00600     // check to see there is a Domain linked to the Model
00601     if (myDomain == 0) {
00602         opserr << "WARNING: AnalysisModel::commitDomain. No Domain linked.\n";
00603         return -1;
00604     }
00605 
00606     // invoke the method
00607     if (myDomain->commit() < 0) {
00608         opserr << "WARNING: AnalysisModel::commitDomain - Domain::commit() failed\n";
00609         return -2;
00610     }
00611 
00612     return 0;
00613 }
00614 
00615 int
00616 AnalysisModel::revertDomainToLastCommit(void)
00617 {
00618     // check to see there is a Domain linked to the Model
00619 
00620     if (myDomain == 0) {
00621         opserr << "WARNING: AnalysisModel::revertDomainToLastCommit.";
00622         opserr << " No Domain linked.\n";
00623         return -1;
00624     }
00625 
00626     // invoke the method
00627     if (myDomain->revertToLastCommit() < 0) {
00628         opserr << "WARNING: AnalysisModel::revertDomainToLastCommit.";
00629         opserr << " Domain::revertToLastCommit() failed.\n";
00630         return -2;
00631     }   
00632     return 0;
00633 }
00634 
00635 double
00636 AnalysisModel::getCurrentDomainTime(void)
00637 {
00638     // check to see there is a Domain linked to the Model
00639 
00640     if (myDomain == 0) {
00641         opserr << "WARNING: AnalysisModel::getCurrentDomainTime.";
00642         opserr << " No Domain linked.\n";
00643         return 0.0;
00644     }
00645 
00646     // invoke the method
00647     return myDomain->getCurrentTime();
00648 }
00649 
00650 
00651 void
00652 AnalysisModel::setCurrentDomainTime(double newTime)
00653 {
00654     if (myDomain == 0) {
00655         opserr << "WARNING: AnalysisModel::getCurrentDomainTime.";
00656         opserr << " No Domain linked.\n";
00657     }
00658 
00659     // invoke the method
00660     myDomain->setCurrentTime(newTime);
00661 }
00662 
00663 
00664 
00665 void
00666 AnalysisModel::setRayleighDampingFactors(double alphaM, double betaK, double betaK0, double betaKc)
00667 {
00668     if (myDomain == 0) {
00669         opserr << "WARNING: AnalysisModel::getCurrentDomainTime.";
00670         opserr << " No Domain linked.\n";
00671     }
00672 
00673     // invoke the method
00674     myDomain->setRayleighDampingFactors(alphaM, betaK, betaK0, betaKc);
00675 }
00676 
00677 
00678 
00679 
00680 Domain *
00681 AnalysisModel::getDomainPtr(void) const
00682 {
00683     return myDomain;
00684 }
00685 
00686 
00687 int
00688 AnalysisModel::sendSelf(int cTag, Channel &theChannel)
00689 {
00690     return 0;
00691 }
00692 
00693 
00694 int
00695 AnalysisModel::recvSelf(int cTag, Channel &theChannel, 
00696                         FEM_ObjectBroker &theBroker) 
00697 {
00698     return 0;
00699 }
00700 

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