Domain.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.35 $
00022 // $Date: 2006/09/05 23:03:33 $
00023 // $Source: /usr/local/cvs/OpenSees/SRC/domain/domain/Domain.cpp,v $
00024                                                                         
00025 // Written: fmk 
00026 //
00027 // Purpose: This file contains the class definition for Domain
00028 // Domain is a container class. The class is responsible for holding
00029 // and providing access to the Elements, Nodes, LoadCases, SP_Constraints 
00030 // and MP_Constraints. These objects are all added to the Domain by a 
00031 // ModelBuilder.
00032 //
00033 // What: "@(#) Domain.C, revA"
00034 
00035 #include <stdlib.h>
00036 
00037 #include <OPS_Globals.h>
00038 #include <Domain.h>
00039 
00040 #include <ElementIter.h>
00041 #include <NodeIter.h>
00042 #include <ElementalLoadIter.h>
00043 #include <NodalLoadIter.h>
00044 #include <Element.h>
00045 #include <Node.h>
00046 #include <SP_Constraint.h>
00047 #include <MP_Constraint.h>
00048 #include <NodalLoad.h>
00049 #include <ElementalLoad.h>
00050 #include <LoadPattern.h>
00051 #include <Parameter.h>
00052 
00053 #include <MapOfTaggedObjects.h>
00054 #include <MapOfTaggedObjectsIter.h>
00055 
00056 #include <SingleDomEleIter.h>
00057 #include <SingleDomNodIter.h>
00058 #include <SingleDomSP_Iter.h>
00059 #include <SingleDomMP_Iter.h>
00060 #include <LoadPatternIter.h>
00061 #include <SingleDomAllSP_Iter.h>
00062 
00063 #include <Vertex.h>
00064 #include <Graph.h>
00065 #include <Recorder.h>
00066 #include <MeshRegion.h>
00067 #include <Analysis.h>
00068 #include <FE_Datastore.h>
00069 #include <FEM_ObjectBroker.h>
00070 
00071 Domain::Domain()
00072 :theRecorders(0), numRecorders(0),
00073  currentTime(0.0), committedTime(0.0), dT(0.0), currentGeoTag(0),
00074  hasDomainChangedFlag(false), theDbTag(0), lastGeoSendTag(-1),
00075  dbEle(0), dbNod(0), dbSPs(0), dbMPs(0), dbLPs(0), dbParam(0),
00076  eleGraphBuiltFlag(false),  nodeGraphBuiltFlag(false), theNodeGraph(0), 
00077  theElementGraph(0), 
00078  theRegions(0), numRegions(0), commitTag(0),
00079  theBounds(6), theEigenvalues(0), theEigenvalueSetTime(0), lastChannel(0)
00080 {
00081   
00082     // init the arrays for storing the domain components
00083     theElements = new MapOfTaggedObjects();
00084     theNodes    = new MapOfTaggedObjects();
00085     theSPs      = new MapOfTaggedObjects();
00086     theMPs      = new MapOfTaggedObjects();    
00087     theLoadPatterns = new MapOfTaggedObjects();
00088     theParameters   = new MapOfTaggedObjects();
00089 
00090     // init the iters    
00091     theEleIter = new SingleDomEleIter(theElements);    
00092     theNodIter = new SingleDomNodIter(theNodes);
00093     theSP_Iter = new SingleDomSP_Iter(theSPs);
00094     theMP_Iter = new SingleDomMP_Iter(theMPs);
00095     theLoadPatternIter = new LoadPatternIter(theLoadPatterns);
00096     allSP_Iter = new SingleDomAllSP_Iter(*this);
00097     
00098     // check that there was space to create the data structures    
00099     if (theElements ==0 || theNodes == 0 || 
00100         theSPs == 0 || theMPs == 0 || 
00101         theEleIter == 0 || theNodIter == 0 || 
00102         theMP_Iter == 0 || theSP_Iter == 0 ||
00103         theLoadPatterns == 0 || theLoadPatternIter == 0 ||
00104         theParameters == 0) {   
00105 
00106       opserr << "Domain::Domain() - out of memory\n";
00107       exit(-1);
00108     }
00109     
00110     theBounds(0) = 0;
00111     theBounds(1) = 0;
00112     theBounds(2) = 0;
00113     theBounds(3) = 0;
00114     theBounds(4) = 0;    
00115     theBounds(5) = 0;            
00116 }
00117 
00118 
00119 Domain::Domain(int numNodes, int numElements, int numSPs, int numMPs,
00120                int numLoadPatterns)
00121 :theRecorders(0), numRecorders(0),
00122  currentTime(0.0), committedTime(0.0), dT(0.0), currentGeoTag(0),
00123  hasDomainChangedFlag(false), theDbTag(0), lastGeoSendTag(-1),
00124  dbEle(0), dbNod(0), dbSPs(0), dbMPs(0), dbLPs(0), dbParam(0),
00125  eleGraphBuiltFlag(false), nodeGraphBuiltFlag(false), theNodeGraph(0), 
00126  theElementGraph(0),
00127  theRegions(0), numRegions(0), commitTag(0),
00128  theBounds(6), theEigenvalues(0), theEigenvalueSetTime(0), lastChannel(0)
00129 {
00130     // init the arrays for storing the domain components
00131     theElements = new MapOfTaggedObjects();
00132     theNodes    = new MapOfTaggedObjects();
00133     theSPs      = new MapOfTaggedObjects();
00134     theMPs      = new MapOfTaggedObjects();    
00135     theLoadPatterns = new MapOfTaggedObjects();
00136     theParameters   = new MapOfTaggedObjects();
00137     
00138     // init the iters
00139     theEleIter = new SingleDomEleIter(theElements);    
00140     theNodIter = new SingleDomNodIter(theNodes);
00141     theSP_Iter = new SingleDomSP_Iter(theSPs);
00142     theMP_Iter = new SingleDomMP_Iter(theMPs);
00143     theLoadPatternIter = new LoadPatternIter(theLoadPatterns);
00144     allSP_Iter = new SingleDomAllSP_Iter(*this);
00145     
00146     // check that there was space to create the data structures    
00147     if (theElements ==0 || theNodes == 0 || 
00148         theSPs == 0 || theMPs == 0 || 
00149         theEleIter == 0 || theNodIter == 0 || 
00150         theMP_Iter == 0 || theSP_Iter == 0 ||
00151         theLoadPatterns == 0 || theLoadPatternIter == 0 ||
00152         theParameters == 0) {   
00153 
00154         opserr << ("Domain::Domain(int, int, ...) - out of memory\n");
00155     }
00156     
00157     theBounds(0) = 0;
00158     theBounds(1) = 0;
00159     theBounds(2) = 0;
00160     theBounds(3) = 0;
00161     theBounds(4) = 0;    
00162     theBounds(5) = 0;            
00163 }
00164 
00165 
00166 Domain::Domain(TaggedObjectStorage &theNodesStorage,
00167                TaggedObjectStorage &theElementsStorage,
00168                TaggedObjectStorage &theMPsStorage,
00169                TaggedObjectStorage &theSPsStorage,
00170                TaggedObjectStorage &theLoadPatternsStorage)
00171 :theRecorders(0), numRecorders(0),
00172  currentTime(0.0), committedTime(0.0), dT(0.0), currentGeoTag(0),
00173  hasDomainChangedFlag(false), theDbTag(0), lastGeoSendTag(-1),
00174  dbEle(0), dbNod(0), dbSPs(0), dbMPs(0), dbLPs(0), dbParam(0),
00175  eleGraphBuiltFlag(false), nodeGraphBuiltFlag(false), theNodeGraph(0), 
00176  theElementGraph(0), 
00177  theElements(&theElementsStorage),
00178  theNodes(&theNodesStorage),
00179  theSPs(&theSPsStorage),
00180  theMPs(&theMPsStorage), 
00181  theLoadPatterns(&theLoadPatternsStorage),
00182  theRegions(0), numRegions(0), commitTag(0),
00183  theBounds(6), theEigenvalues(0), theEigenvalueSetTime(0), lastChannel(0)
00184 {
00185     // init the iters    
00186     theEleIter = new SingleDomEleIter(theElements);    
00187     theNodIter = new SingleDomNodIter(theNodes);
00188     theSP_Iter = new SingleDomSP_Iter(theSPs);
00189     theMP_Iter = new SingleDomMP_Iter(theMPs);
00190     theLoadPatternIter = new LoadPatternIter(theLoadPatterns);
00191     allSP_Iter = new SingleDomAllSP_Iter(*this);
00192 
00193     // check that the containers are empty
00194     if (theElements->getNumComponents() != 0 ||
00195         theNodes->getNumComponents() != 0 ||
00196         theSPs->getNumComponents() != 0 ||
00197         theMPs->getNumComponents() != 0 ||
00198         theLoadPatterns->getNumComponents() != 0 ) {
00199 
00200         opserr << ("Domain::Domain(&, & ...) - out of memory\n");       
00201     }           
00202         
00203     // check that there was space to create the data structures    
00204     if (theElements ==0 || theNodes == 0 || 
00205         theSPs == 0 || theMPs == 0 || 
00206         theEleIter == 0 || theNodIter == 0 ||
00207         theMP_Iter == 0 || theSP_Iter == 0 ||
00208         theLoadPatterns == 0 || theLoadPatternIter == 0) { 
00209     
00210         opserr << "FATAL Domain::Domain(TaggedObjectStorage, ...) - ";
00211         opserr << "Ran out of memory\n";
00212         exit(-1);
00213     }    
00214     
00215     theBounds(0) = 0;
00216     theBounds(1) = 0;
00217     theBounds(2) = 0;
00218     theBounds(3) = 0;
00219     theBounds(4) = 0;    
00220     theBounds(5) = 0;            
00221 }    
00222 
00223 
00224 
00225 Domain::Domain(TaggedObjectStorage &theStorage)
00226 :theRecorders(0), numRecorders(0),
00227  currentTime(0.0), committedTime(0.0), dT(0.0), currentGeoTag(0),
00228  hasDomainChangedFlag(false), theDbTag(0), lastGeoSendTag(-1),
00229  dbEle(0), dbNod(0), dbSPs(0), dbMPs(0), dbLPs(0), dbParam(0),
00230  eleGraphBuiltFlag(false), nodeGraphBuiltFlag(false), theNodeGraph(0), 
00231  theElementGraph(0), 
00232  theRegions(0), numRegions(0), commitTag(0),
00233  theBounds(6), theEigenvalues(0), theEigenvalueSetTime(0), lastChannel(0)
00234 {
00235     // init the arrays for storing the domain components
00236     theStorage.clearAll(); // clear the storage just in case populated
00237     theElements = &theStorage;
00238     theNodes    = theStorage.getEmptyCopy();
00239     theSPs      = theStorage.getEmptyCopy();
00240     theMPs      = theStorage.getEmptyCopy();
00241     theLoadPatterns = theStorage.getEmptyCopy();    
00242     theParameters   = theStorage.getEmptyCopy();    
00243 
00244     // init the iters    
00245     theEleIter = new SingleDomEleIter(theElements);    
00246     theNodIter = new SingleDomNodIter(theNodes);
00247     theSP_Iter = new SingleDomSP_Iter(theSPs);
00248     theMP_Iter = new SingleDomMP_Iter(theMPs);
00249     theLoadPatternIter = new LoadPatternIter(theLoadPatterns);
00250     allSP_Iter = new SingleDomAllSP_Iter(*this);
00251 
00252     // check that there was space to create the data structures    
00253     if (theElements ==0 || theNodes == 0 || 
00254         theSPs == 0 || theMPs == 0 || 
00255         theEleIter == 0 || theNodIter == 0 ||
00256         theMP_Iter == 0 || theSP_Iter == 0 ||
00257         theLoadPatterns == 0 || theLoadPatternIter == 0 ||
00258         theParameters == 0) { 
00259         
00260         opserr << ("Domain::Domain(ObjectStorage &) - out of memory\n");        
00261     }
00262     
00263     theBounds(0) = 0;
00264     theBounds(1) = 0;
00265     theBounds(2) = 0;
00266     theBounds(3) = 0;
00267     theBounds(4) = 0;    
00268     theBounds(5) = 0;            
00269 
00270     dbEle =0; dbNod =0; dbSPs =0; dbMPs =0; dbLPs = 0; dbParam = 0;
00271 }
00272 
00273 
00274 
00275 
00276 
00277 // ~Domain();    
00278 //      destructor, this calls delete on all components of the model,
00279 //      i.e. calls delete on all that is added to the model.
00280 //      WARNING: if 3rd constructor, TaggedObjectStorage objects passed 
00281 //      must have been created with new and nowhere else must the
00282 //      destructor be called.
00283 
00284 Domain::~Domain()
00285 {
00286   // delete the objects in the domain
00287   this->Domain::clearAll();
00288 
00289   // delete all the storage objects
00290   // SEGMENT FAULT WILL OCCUR IF THESE OBJECTS WERE NOT CONSTRUCTED
00291   // USING NEW
00292   
00293   if (theElements != 0)
00294     delete theElements;    
00295   
00296   if (theNodes != 0)
00297     delete theNodes;
00298   
00299   if (theSPs != 0)
00300     delete theSPs;
00301   
00302   if (theMPs != 0)
00303     delete theMPs;
00304   
00305   if (theLoadPatterns != 0)
00306     delete theLoadPatterns;
00307 
00308   if (theParameters != 0)
00309     delete theParameters;
00310   
00311   if (theEleIter != 0)
00312     delete theEleIter;
00313   
00314   if (theNodIter != 0)
00315     delete theNodIter;
00316   
00317   if (theSP_Iter != 0)
00318     delete theSP_Iter;
00319   
00320   if (theMP_Iter != 0)
00321     delete theMP_Iter;
00322   
00323   if (allSP_Iter != 0)
00324     delete allSP_Iter;
00325   
00326   if (theEigenvalues != 0)
00327     delete theEigenvalues;
00328   
00329   int i;
00330   for (i=0; i<numRecorders; i++)  
00331     delete theRecorders[i];
00332   
00333   if (theRecorders != 0) {
00334     delete [] theRecorders;
00335     theRecorders = 0;
00336   }
00337   
00338   for (i=0; i<numRegions; i++)  
00339     delete theRegions[i];
00340   
00341   if (theRegions != 0) {
00342     delete [] theRegions;
00343     theRegions = 0;
00344   }
00345   
00346   theRecorders = 0;
00347   numRecorders = 0;
00348 }
00349 
00350 
00351 // void addElement(Element *);
00352 //      Method to add an element to the model.
00353 
00354 
00355 bool
00356 Domain::addElement(Element *element)
00357 {
00358   int eleTag = element->getTag();
00359 
00360 #ifdef _G3DEBUG
00361   // check all the elements nodes exist in the domain
00362   const ID &nodes = element->getExternalNodes();
00363   int numDOF = 0;
00364   for (int i=0; i<nodes.Size(); i++) {
00365       int nodeTag = nodes(i);
00366       Node *nodePtr = this->getNode(nodeTag);
00367       if (nodePtr == 0) {
00368           opserr << "WARNING Domain::addElement - In element " << *element;
00369           opserr << "\n no Node " << nodeTag << " exists in the domain\n";
00370           return false;
00371       }
00372       numDOF += nodePtr->getNumberDOF();
00373   }   
00374 #endif
00375 
00376   // check if an Element with a similar tag already exists in the Domain
00377   TaggedObject *other = theElements->getComponentPtr(eleTag);
00378   if (other != 0) {
00379     opserr << "Domain::addElement - element with tag " << eleTag << "already exists in model\n"; 
00380     return false;
00381   }
00382 
00383   // add the element to the container object for the elements
00384   bool result = theElements->addComponent(element);
00385   if (result == true) {
00386     element->setDomain(this);
00387         element->update();
00388 
00389     // finally check the ele has correct number of dof
00390 #ifdef _G3DEBUG
00391     if (numDOF != element->getNumDOF()) { 
00392       
00393       opserr << "Domain::addElement - element " << eleTag << " - #DOF does not match with number at nodes\n";
00394       theElements->removeComponent(eleTag);
00395       return false;
00396     }
00397 #endif      
00398 
00399     // mark the Domain as having been changed
00400     this->domainChange();
00401   } else 
00402     opserr << "Domain::addElement - element " << eleTag << "could not be added to container\n";      
00403 
00404   return result;
00405 }
00406 
00407 
00408 
00409 // void addNode(Node *);
00410 //      Method to add a Node to the model.
00411 
00412 bool
00413 Domain::addNode(Node * node)
00414 {
00415   int nodTag = node->getTag();
00416 
00417   TaggedObject *other = theNodes->getComponentPtr(nodTag);
00418   if (other != 0) {
00419     opserr << "Domain::addNode - node with tag " << nodTag << "already exists in model\n"; 
00420     return false;
00421   }
00422   
00423   bool result = theNodes->addComponent(node);
00424   if (result == true) {
00425       node->setDomain(this);
00426       this->domainChange();
00427       
00428       // see if the physical bounds are changed
00429       // note this assumes 0,0,0,0,0,0 as startup min,max values
00430       const Vector &crds = node->getCrds();
00431       int dim = crds.Size();
00432       if (dim >= 1) {
00433           double x = crds(0);
00434           if (x < theBounds(0)) theBounds(0) = x;
00435           if (x > theBounds(3)) theBounds(3) = x;
00436       } 
00437       if (dim >= 2) {
00438           double y = crds(1);
00439           if (y < theBounds(1)) theBounds(1) = y;
00440           if (y > theBounds(4)) theBounds(4) = y;         
00441       } 
00442       if (dim == 3) {
00443           double z = crds(2);
00444           if (z < theBounds(2)) theBounds(2) = z;
00445           if (z > theBounds(5)) theBounds(5) = z;         
00446       }
00447       
00448   } else
00449     opserr << "Domain::addNode - node with tag " << nodTag << "could not be added to container\n";
00450 
00451   return result;
00452 }
00453 
00454 
00455 // void addSP_Constraint(SP_Constraint *);
00456 //      Method to add a constraint to the model.
00457 //
00458 
00459 bool
00460 Domain::addSP_Constraint(SP_Constraint *spConstraint)
00461 {
00462 #ifdef _G3DEBUG    
00463     // check the Node exists in the Domain
00464     int nodeTag = spConstraint->getNodeTag();
00465     Node *nodePtr = this->getNode(nodeTag);
00466     if (nodePtr == 0) {
00467       opserr << "Domain::addSP_Constraint - cannot add as node node with tag" <<
00468         nodeTag << "does not exist in model\n";         
00469       return false;
00470     }
00471 
00472     // check that the DOF specified exists at the Node
00473     int numDOF = nodePtr->getNumberDOF();
00474     if (numDOF < spConstraint->getDOF_Number()) {
00475         opserr << "Domain::addSP_Constraint - cannot add as node node with tag" << 
00476           nodeTag << "does not have associated constrained DOF\n"; 
00477         return false;
00478     }      
00479 #endif
00480 
00481   // check that no other object with similar tag exists in model
00482   int tag = spConstraint->getTag();
00483   TaggedObject *other = theSPs->getComponentPtr(tag);
00484   if (other != 0) {
00485     opserr << "Domain::addSP_Constraint - cannot add as constraint with tag" << 
00486       tag << "already exists in model\n";             
00487     return false;
00488   }
00489   
00490   bool result = theSPs->addComponent(spConstraint);
00491   if (result == false) {
00492       opserr << "Domain::addSP_Constraint - cannot add constraint with tag" << 
00493         tag << "to the container\n";             
00494       return false;
00495   } 
00496 
00497   spConstraint->setDomain(this);
00498   this->domainChange();  
00499 
00500   return true;
00501 }
00502 
00503 
00504 // void addMP_Constraint(MP_Constraint *);
00505 //      Method to add a constraint to the model.
00506 //
00507 
00508 bool
00509 Domain::addMP_Constraint(MP_Constraint *mpConstraint)
00510 {
00511 #ifdef _G3DEBUG
00512     // perform the checks
00513     int nodeConstrained = mpConstraint->getNodeConstrained();
00514     Node *nodePtr = this->getNode(nodeConstrained);
00515     if (nodePtr == 0) {
00516       opserr << "Domain::addMP_Constraint -cannot add as constrained node with tag" <<
00517         nodeConstrained << "does not exist in model\n";                 
00518       return false;
00519     }
00520     
00521     int nodeRetained = mpConstraint->getNodeRetained();      
00522     nodePtr = this->getNode(nodeRetained);
00523     if (nodePtr == 0) {
00524       opserr << "Domain::addMP_Constraint - cannot add as retained node with tag" <<
00525         nodeRetained << "does not exist in model\n";    
00526       
00527       return false;
00528     }      
00529     // MISSING CODE
00530 #endif
00531 
00532   // check that no other object with similar tag exists in model
00533   int tag = mpConstraint->getTag();
00534   TaggedObject *other = theMPs->getComponentPtr(tag);
00535   if (other != 0) {
00536     opserr << "Domain::addMP_Constraint - cannot add as constraint with tag" <<
00537       tag << "already exists in model";             
00538                               
00539     return false;
00540   }
00541   
00542   bool result = theMPs->addComponent(mpConstraint);
00543   if (result == true) {
00544       mpConstraint->setDomain(this);
00545       this->domainChange();
00546   } else
00547     opserr << "Domain::addMP_Constraint - cannot add constraint with tag" << 
00548       tag << "to the container\n";                   
00549                               
00550   return result;
00551 }
00552 
00553 bool 
00554 Domain::addLoadPattern(LoadPattern *load)
00555 {
00556     // first check if a load pattern with a similar tag exists in model
00557     int tag = load->getTag();
00558     TaggedObject *other = theLoadPatterns->getComponentPtr(tag);
00559     if (other != 0) {
00560       opserr << "Domain::addLoadPattern - cannot add as LoadPattern with tag" <<
00561         tag << "already exists in model\n";             
00562                                 
00563       return false;
00564     }    
00565 
00566     // now we add the load pattern to the container for load pattrens
00567     bool result = theLoadPatterns->addComponent(load);
00568     if (result == true) {
00569         load->setDomain(this);
00570         this->domainChange();
00571     }
00572     else 
00573       opserr << "Domain::addLoadPattern - cannot add LoadPattern with tag" <<
00574         tag << "to the container\n";                    
00575                               
00576     return result;
00577 }    
00578 
00579 bool
00580 Domain::addParameter(Parameter *param)
00581 {
00582   int paramTag = param->getTag();
00583 
00584   // check if a Parameter with a similar tag already exists in the Domain
00585   TaggedObject *other = theParameters->getComponentPtr(paramTag);
00586   if (other != 0) {
00587     opserr << "Domain::addParameter - parameter with tag " << paramTag << "already exists in model\n"; 
00588     return false;
00589   }
00590 
00591   // add the param to the container object for the parameters
00592   bool result = theParameters->addComponent(param);
00593   if (result == true) {
00594     // mark the Domain as having been changed
00595     this->domainChange();
00596   } else 
00597     opserr << "Domain::addParameter - parameter " << paramTag << "could not be added to container\n";      
00598 
00599   return result;
00600 }
00601 
00602 bool
00603 Domain::addSP_Constraint(SP_Constraint *spConstraint, int pattern)
00604 {
00605 #ifdef _G3DEBUG
00606     // check the Node exists in the Domain
00607     int nodeTag = spConstraint->getNodeTag();
00608     Node *nodePtr = this->getNode(nodeTag);
00609     if (nodePtr == 0) {
00610       opserr << "Domain::addSP_Constraint - cannot add as node with tag" <<
00611         nodeTag << "does not exist in model\n";
00612         return false;
00613     }
00614 
00615     // check that the DOF specified exists at the Node
00616     int numDOF = nodePtr->getNumberDOF();
00617     if (numDOF < spConstraint->getDOF_Number()) {
00618       opserr << "Domain::addSP_Constraint - cannot add as node with tag" <<
00619         nodeTag << "does not have associated constrained DOF\n"; 
00620 
00621         return false;
00622     }      
00623 #endif
00624 
00625   // now add it to the pattern
00626   TaggedObject *thePattern = theLoadPatterns->getComponentPtr(pattern);
00627   if (thePattern == 0) {
00628       opserr << "Domain::addSP_Constraint - cannot add as pattern with tag" <<
00629         pattern << "does not exist in domain\n"; 
00630                               
00631       return false;
00632   }
00633   LoadPattern *theLoadPattern = (LoadPattern *)thePattern;
00634   bool result = theLoadPattern->addSP_Constraint(spConstraint);
00635   if (result == false) {
00636     opserr << "Domain::addSP_Constraint - " << pattern << "pattern could not add the SP_Constraint\n"; 
00637                               
00638     return false;
00639   }
00640 
00641   spConstraint->setDomain(this);
00642   this->domainChange();  
00643 
00644   return true;
00645 }
00646 
00647 bool 
00648 Domain::addNodalLoad(NodalLoad *load, int pattern)
00649 {
00650     int nodTag = load->getNodeTag();
00651     Node *res = this->getNode(nodTag);
00652     if (res == 0) {
00653       opserr << "Domain::addNodalLoad() HI - no node with tag " << nodTag << 
00654         "exits in  the model, not adding the nodal load"  << *load << endln;
00655         return false;
00656     }
00657 
00658     // now add it to the pattern
00659     TaggedObject *thePattern = theLoadPatterns->getComponentPtr(pattern);
00660     if (thePattern == 0) {
00661       opserr << "Domain::addNodalLoad() - no pattern with tag" << 
00662         pattern << "in  the model, not adding the nodal load"  << *load << endln;
00663       
00664         return false;
00665     }
00666     LoadPattern *theLoadPattern = (LoadPattern *)thePattern;
00667     bool result = theLoadPattern->addNodalLoad(load);
00668     if (result == false) {
00669       opserr << "Domain::addNodalLoad() - pattern with tag" << 
00670         pattern << "could not add the load" << *load << endln;
00671                                 
00672       return false;
00673     }
00674 
00675     load->setDomain(this);    // done in LoadPattern::addNodalLoad()
00676     this->domainChange();
00677 
00678     return result;
00679 }    
00680 
00681 
00682 bool 
00683 Domain::addElementalLoad(ElementalLoad *load, int pattern)
00684 {
00685     // now add it to the pattern
00686     TaggedObject *thePattern = theLoadPatterns->getComponentPtr(pattern);
00687     if (thePattern == 0) {
00688       opserr << "Domain::addNodalLoad() - no pattern with tag " << pattern << 
00689         "exits in  the model, not adding the ele load " << *load << endln;
00690 
00691         return false;
00692     }
00693     LoadPattern *theLoadPattern = (LoadPattern *)thePattern;
00694     bool result = theLoadPattern->addElementalLoad(load);
00695     if (result == false) {
00696       opserr << "Domain::addNodalLoad() - no pattern with tag" << 
00697         pattern << "in  the model, not adding the ele load" << *load << endln;
00698       return false;
00699     }
00700 
00701 
00702     // load->setDomain(this); // done in LoadPattern::addElementalLoad()
00703     this->domainChange();
00704     return result;
00705 }
00706 
00707 
00708 /* GENERAL NOTE ON REMOVAL OF COMPONENTS:
00709 **   downward casts (while bad) are o.k. as only the type
00710 **   of components can be added to the storage objects, e.g.
00711 **   only elements can be added to theElements therefore
00712 **   casting a DomainComponent from theElements to an Element is o.k.
00713 */
00714 
00715 void
00716 Domain::clearAll(void) {
00717   // clear the loads and constraints from any load pattern
00718   LoadPatternIter &thePatterns = this->getLoadPatterns();
00719   LoadPattern *thePattern;
00720   while ((thePattern = thePatterns()) != 0)
00721     thePattern->clearAll();
00722   
00723   // clean out the containers
00724   theElements->clearAll();
00725   theNodes->clearAll();
00726   theSPs->clearAll();
00727   theMPs->clearAll();
00728   theLoadPatterns->clearAll();
00729   theParameters->clearAll();
00730 
00731   // remove the recorders
00732   int i;
00733   for (i=0; i<numRecorders; i++)
00734     delete theRecorders[i];
00735   numRecorders = 0; 
00736   
00737   if (theRecorders != 0) {
00738     delete [] theRecorders;
00739     theRecorders = 0;
00740   }
00741   
00742   for (i=0; i<numRegions; i++)
00743     delete theRegions[i];
00744   numRegions = 0;
00745 
00746   if (theRegions != 0) {
00747     delete [] theRegions;
00748     theRegions = 0;
00749   }
00750   
00751   // set the time back to 0.0
00752   currentTime = 0.0;
00753   committedTime = 0.0;
00754   dT = 0.0;
00755 
00756   // set the bounds around the origin
00757   theBounds(0) = 0;
00758   theBounds(1) = 0;
00759   theBounds(2) = 0;
00760   theBounds(3) = 0;
00761   theBounds(4) = 0;    
00762   theBounds(5) = 0;        
00763   
00764   currentGeoTag = 0;
00765   lastGeoSendTag = -1;
00766   
00767   // rest the flag to be as initial
00768   hasDomainChangedFlag = false;
00769   nodeGraphBuiltFlag = false;
00770   eleGraphBuiltFlag = false;
00771   
00772   dbEle =0; dbNod =0; dbSPs =0; dbMPs =0; dbLPs = 0; dbParam = 0;
00773 
00774   currentGeoTag = 0;
00775   lastGeoSendTag = -1;
00776   lastChannel = 0;
00777 
00778   // rest the flag to be as initial
00779   hasDomainChangedFlag = false;
00780   nodeGraphBuiltFlag = false;
00781   eleGraphBuiltFlag = false;
00782 
00783   if (theNodeGraph != 0)
00784     delete theNodeGraph;
00785   theNodeGraph = 0;
00786 
00787   if (theElementGraph != 0)
00788     delete theElementGraph;
00789   theElementGraph = 0;
00790   
00791   dbEle =0; dbNod =0; dbSPs =0; dbMPs =0; dbLPs = 0; dbParam = 0;
00792 }
00793 
00794 
00795 Element *
00796 Domain::removeElement(int tag)
00797 {
00798   // remove the object from the container    
00799   TaggedObject *mc = theElements->removeComponent(tag);
00800   
00801   // if not there return 0
00802   if (mc == 0) 
00803       return 0;
00804 
00805   // otherwise mark the domain as having changed
00806   this->domainChange();
00807   
00808   // perform a downward cast to an Element (safe as only Element added to
00809   // this container, 0 the Elements DomainPtr and return the result of the cast  
00810   Element *result = (Element *)mc;
00811   //  result->setDomain(0);
00812   return result;
00813 }
00814 
00815 Node *
00816 Domain::removeNode(int tag)
00817 {
00818   // remove the object from the container
00819   TaggedObject *mc = theNodes->removeComponent(tag);
00820   
00821   // if not there return 0
00822   if (mc == 0) 
00823       return 0;  
00824 
00825   // mark the domain has having changed 
00826   this->domainChange();
00827   
00828   // perform a downward cast to a Node (safe as only Node added to
00829   // this container and return the result of the cast
00830   Node *result = (Node *)mc;
00831   // result->setDomain(0);
00832   return result;
00833 }
00834 
00835 
00836 SP_Constraint *
00837 Domain::removeSP_Constraint(int tag)
00838 {
00839     // remove the object from the container    
00840     TaggedObject *mc = theSPs->removeComponent(tag);
00841     
00842     // if not there return 0    
00843     if (mc == 0) 
00844         return 0;
00845 
00846     // mark the domain as having changed    
00847     this->domainChange();
00848     
00849     // perform a downward cast, set the objects domain pointer to 0
00850     // and return the result of the cast    
00851     SP_Constraint *result = (SP_Constraint *)mc;
00852     // result->setDomain(0);
00853 
00854     // should check that theLoad and result are the same    
00855     return result;
00856 }
00857 
00858 MP_Constraint *
00859 Domain::removeMP_Constraint(int tag)
00860 {
00861     // remove the object from the container        
00862     TaggedObject *mc = theMPs->removeComponent(tag);
00863     
00864     // if not there return 0    
00865     if (mc == 0) 
00866         return 0;
00867 
00868     // mark the domain as having changed    
00869     this->domainChange();
00870     
00871     // perform a downward cast, set the objects domain pointer to 0
00872     // and return the result of the cast        
00873     MP_Constraint *result = (MP_Constraint *)mc;
00874     // result->setDomain(0);
00875     return result;
00876 }    
00877 
00878 Parameter *
00879 Domain::removeParameter(int tag)
00880 {
00881   // remove the object from the container    
00882   TaggedObject *mc = theParameters->removeComponent(tag);
00883   
00884   // if not there return 0
00885   if (mc == 0) 
00886       return 0;
00887 
00888   // otherwise mark the domain as having changed
00889   this->domainChange();
00890   
00891   // perform a downward cast to an Element (safe as only Element added to
00892   // this container, 0 the Elements DomainPtr and return the result of the cast  
00893   Parameter *result = (Parameter *)mc;
00894   //  result->setDomain(0);
00895   return result;
00896 }
00897 
00898 LoadPattern *
00899 Domain::removeLoadPattern(int tag)
00900 {
00901     // remove the object from the container            
00902     TaggedObject *obj = theLoadPatterns->removeComponent(tag);
00903     
00904     // if not there return 0    
00905     if (obj == 0)
00906         return 0;
00907     
00908     // perform a downward cast, set the objects domain pointer to 0
00909     // and return the result of the cast            
00910     LoadPattern *result = (LoadPattern *)obj;
00911     // result->setDomain(0);
00912 
00913     //
00914     // now set the Domain pointer for all loads and SP constraints 
00915     // in the loadPattern to be 0
00916     //
00917     
00918     NodalLoad *theNodalLoad;
00919     NodalLoadIter &theNodalLoads = result->getNodalLoads();
00920     while ((theNodalLoad = theNodalLoads()) != 0) {
00921       // theNodalLoad->setDomain(0);
00922     }
00923 
00924     ElementalLoad *theElementalLoad;
00925     ElementalLoadIter &theElementalLoads = result->getElementalLoads();
00926     while ((theElementalLoad = theElementalLoads()) != 0) {
00927       // theElementalLoad->setDomain(0);
00928     }
00929 
00930     int numSPs = 0;
00931     SP_Constraint *theSP_Constraint;
00932     SP_ConstraintIter &theSP_Constraints = result->getSPs();
00933     while ((theSP_Constraint = theSP_Constraints()) != 0) {
00934         numSPs++;
00935         // theSP_Constraint->setDomain(0);
00936     }
00937 
00938     // mark the domain has having changed if numSPs > 0
00939     // as the constraint handlers have to be redone
00940     if (numSPs > 0)
00941         this->domainChange();
00942 
00943     // finally return the load pattern
00944     return result;    
00945 }    
00946 
00947 
00948 
00949 
00950 
00951 NodalLoad *
00952 Domain::removeNodalLoad(int tag, int loadPattern)
00953 {
00954   // remove the object from the container            
00955   LoadPattern *theLoadPattern = this->getLoadPattern(loadPattern);
00956     
00957   // if not there return 0    
00958   if (theLoadPattern == 0)
00959     return 0;
00960     
00961   return theLoadPattern->removeNodalLoad(tag);
00962 }    
00963 
00964 
00965 ElementalLoad *
00966 Domain::removeElementalLoad(int tag, int loadPattern)
00967 {
00968   // remove the object from the container            
00969   LoadPattern *theLoadPattern = this->getLoadPattern(loadPattern);
00970     
00971   // if not there return 0    
00972   if (theLoadPattern == 0)
00973     return 0;
00974     
00975   return theLoadPattern->removeElementalLoad(tag);
00976 }    
00977 
00978 
00979 SP_Constraint *
00980 Domain::removeSP_Constraint(int tag, int loadPattern)
00981 {
00982   // remove the object from the container            
00983   LoadPattern *theLoadPattern = this->getLoadPattern(loadPattern);
00984     
00985   // if not there return 0    
00986   if (theLoadPattern == 0)
00987     return 0;
00988     
00989   SP_Constraint *theSP = theLoadPattern->removeSP_Constraint(tag);
00990   if (theSP != 0)
00991     this->domainChange();
00992 
00993   return theSP;
00994 }    
00995 
00996 ElementIter &
00997 Domain::getElements()
00998 {
00999     theEleIter->reset();    
01000     return *theEleIter;
01001 }
01002 
01003 
01004 NodeIter &
01005 Domain::getNodes()
01006 {
01007     theNodIter->reset();    
01008     return *theNodIter;
01009 }
01010 
01011 SP_ConstraintIter &
01012 Domain::getSPs()
01013 {
01014     theSP_Iter->reset();
01015     return *theSP_Iter;;
01016 }
01017 
01018 SP_ConstraintIter &
01019 Domain::getDomainAndLoadPatternSPs()
01020 {
01021     allSP_Iter->reset();
01022     return *allSP_Iter;;
01023 }
01024 
01025 
01026 MP_ConstraintIter &
01027 Domain::getMPs()
01028 {
01029     theMP_Iter->reset();
01030     return *theMP_Iter;;
01031 }
01032 
01033 
01034 LoadPatternIter &
01035 Domain::getLoadPatterns()
01036 {
01037     theLoadPatternIter->reset();
01038     return *theLoadPatternIter;;
01039 }
01040 
01041 /* GENERAL NOTE ON RETRIEVAL OF COMPONENT PTRs:
01042 **   downward casts (while bad) are o.k. as only the type
01043 **   of components can be added to the storage objects, e.g.
01044 **   only elements can be added to theElements
01045 */
01046 
01047 Element *
01048 Domain::getElement(int tag) 
01049 {
01050   TaggedObject *mc = theElements->getComponentPtr(tag);
01051   
01052   // if not there return 0 otherwise perform a cast and return that
01053   if (mc == 0) 
01054       return 0;
01055   Element *result = (Element *)mc;
01056   return result;
01057 }
01058 
01059 
01060 Node *
01061 Domain::getNode(int tag) 
01062 {
01063   TaggedObject *mc = theNodes->getComponentPtr(tag);
01064 
01065   // if not there return 0 otherwise perform a cast and return that  
01066   if (mc == 0) 
01067       return 0;  
01068   Node *result = (Node *)mc;
01069   return result;
01070 }
01071 
01072 SP_Constraint *
01073 Domain::getSP_Constraint(int tag) 
01074 {
01075   TaggedObject *mc = theSPs->getComponentPtr(tag);
01076 
01077   // if not there return 0 otherwise perform a cast and return that  
01078   if (mc == 0) 
01079       return 0;
01080   SP_Constraint *result = (SP_Constraint *)mc;
01081   return result;
01082 }
01083 
01084 MP_Constraint *
01085 Domain::getMP_Constraint(int tag) 
01086 {
01087   TaggedObject *mc = theMPs->getComponentPtr(tag);
01088 
01089   // if not there return 0 otherwise perform a cast and return that
01090   if (mc == 0) 
01091       return 0;
01092   MP_Constraint *result = (MP_Constraint *)mc;
01093   return result;
01094 }
01095 
01096 Parameter *
01097 Domain::getParameter(int tag) 
01098 {
01099   TaggedObject *mc = theParameters->getComponentPtr(tag);
01100 
01101   // if not there return 0 otherwise perform a cast and return that
01102   if (mc == 0) 
01103       return 0;
01104   Parameter *result = (Parameter *)mc;
01105   return result;
01106 }
01107 
01108 LoadPattern *
01109 Domain::getLoadPattern(int tag) 
01110 {
01111   TaggedObject *mc = theLoadPatterns->getComponentPtr(tag);
01112   // if not there return 0 otherwise perform a cast and return that  
01113   if (mc == 0) 
01114       return 0;
01115   LoadPattern *result = (LoadPattern *)mc;
01116   return result;
01117 }
01118 
01119 
01120 double
01121 Domain::getCurrentTime(void) const
01122 {
01123     return currentTime;
01124 }
01125 
01126 int
01127 Domain::getCommitTag(void) const
01128 {
01129   return commitTag;
01130 }
01131 
01132 
01133 int 
01134 Domain::getNumElements(void) const
01135 {
01136     return theElements->getNumComponents();
01137 }
01138 int 
01139 Domain::getNumNodes(void) const
01140 {
01141     return theNodes->getNumComponents();
01142 }
01143 
01144 int 
01145 Domain::getNumSPs(void) const
01146 {
01147     return theSPs->getNumComponents();
01148 }
01149 
01150 
01151 int 
01152 Domain::getNumMPs(void) const
01153 {
01154     return theMPs->getNumComponents();
01155 }
01156 
01157 int 
01158 Domain::getNumLoadPatterns(void) const
01159 {
01160     return theLoadPatterns->getNumComponents();
01161 }
01162 
01163 int 
01164 Domain::getNumParameters(void) const
01165 {
01166     return theParameters->getNumComponents();
01167 }
01168 
01169 const Vector &
01170 Domain::getPhysicalBounds(void)
01171 {
01172     return theBounds;
01173 }
01174 
01175 Graph  &
01176 Domain::getElementGraph(void)
01177 {
01178     if (eleGraphBuiltFlag == false) {
01179         // if the current graph is out of date .. delete it so we can start again
01180         if (theElementGraph != 0) {
01181             delete theElementGraph;
01182             theElementGraph = 0;
01183         }       
01184         // create an empty graph 
01185         theElementGraph = new Graph(this->getNumElements()+START_VERTEX_NUM);
01186 
01187         if (theElementGraph == 0) {// if still 0 try a smaller one
01188             theElementGraph = new Graph();
01189             
01190             if (theElementGraph == 0) { // if still 0 out of memory
01191                 opserr << "Domain::getElementGraph() - out of memory\n";
01192                 exit(-1);
01193             }
01194         }
01195 
01196         // now build the graph
01197         if (this->buildEleGraph(theElementGraph) == 0)
01198             eleGraphBuiltFlag = true;
01199         else
01200             opserr << "Domain::getElementGraph() - failed to build the element graph\n";            
01201     }
01202     
01203     // return the Graph
01204     return *theElementGraph;
01205 }
01206 
01207 
01208 Graph  &
01209 Domain::getNodeGraph(void)
01210 {
01211     if (nodeGraphBuiltFlag == false) {
01212         
01213         // if the current graph is out of date .. delete it so we can start again
01214         if (theNodeGraph != 0) {
01215             delete theNodeGraph;
01216             theNodeGraph = 0;
01217         }
01218 
01219         // try to get a graph as big as we should need
01220         theNodeGraph = new Graph(this->getNumNodes()+START_VERTEX_NUM);
01221         
01222         if (theNodeGraph == 0) { // if still 0 try a smaller one
01223             theNodeGraph = new Graph();
01224 
01225             if (theNodeGraph == 0) {// if still 0 out of memory
01226                 opserr << "Domain::getNodeGraph() - out of memory\n";
01227                 exit(-1);
01228             }
01229         }
01230 
01231        // now build the graph
01232         if (this->buildNodeGraph(theNodeGraph) == 0)
01233             nodeGraphBuiltFlag = true;
01234         else
01235             opserr << "Domain::getNodeGraph() - failed to build the node graph\n";
01236     }
01237 
01238     // return the Graph
01239     return *theNodeGraph;
01240 }
01241 
01242 void
01243 Domain::setCommitTag(int newTag)
01244 {
01245     commitTag = newTag;
01246 }
01247 
01248 void
01249 Domain::setCurrentTime(double newTime)
01250 {
01251     currentTime = newTime;
01252     dT = currentTime - committedTime;
01253 }
01254 
01255 void
01256 Domain::setCommittedTime(double newTime)
01257 {
01258     committedTime = newTime;
01259     dT = currentTime - committedTime;
01260 }
01261 
01262 
01263 void
01264 Domain::applyLoad(double timeStep)
01265 {
01266     // set the current pseudo time in the domai to be newTime
01267     currentTime = timeStep;
01268     dT = currentTime - committedTime;
01269 
01270     //
01271     // first loop over nodes and elements getting them to first zero their loads
01272     //
01273 
01274     Node *nodePtr;
01275     NodeIter &theNodeIter = this->getNodes();
01276     while ((nodePtr = theNodeIter()) != 0)
01277         nodePtr->zeroUnbalancedLoad();
01278 
01279     Element *elePtr;
01280     ElementIter &theElemIter = this->getElements();    
01281     while ((elePtr = theElemIter()) != 0)
01282         if (elePtr->isSubdomain() == false)
01283             elePtr->zeroLoad();    
01284 
01285     // now loop over load patterns, invoking applyLoad on them
01286     LoadPattern *thePattern;
01287     LoadPatternIter &thePatterns = this->getLoadPatterns();
01288     while((thePattern = thePatterns()) != 0)
01289       thePattern->applyLoad(timeStep);
01290 
01291     //
01292     // finally loop over the MP_Constraints and SP_Constraints of the domain
01293     //
01294 
01295     MP_ConstraintIter &theMPs = this->getMPs();
01296     MP_Constraint *theMP;
01297     while ((theMP = theMPs()) != 0)
01298         theMP->applyConstraint(timeStep);
01299 
01300     SP_ConstraintIter &theSPs = this->getSPs();
01301     SP_Constraint *theSP;
01302     while ((theSP = theSPs()) != 0) {
01303         theSP->applyConstraint(timeStep);
01304     }
01305 }
01306 
01307 
01308 void
01309 Domain::setLoadConstant(void)
01310 {
01311     // loop over all the load patterns that are currently added to the domain
01312     // getting them to set their loads as now constant
01313     LoadPattern *thePattern;
01314     LoadPatternIter &thePatterns = this->getLoadPatterns();
01315     while((thePattern = thePatterns()) != 0)
01316       thePattern->setLoadConstant();
01317 }
01318 
01319 
01320 
01321 int
01322 Domain::initialize(void)
01323 {
01324   Element *elePtr;
01325   ElementIter &theElemIter = this->getElements();    
01326   while ((elePtr = theElemIter()) != 0) 
01327     // lvalue needed here for M$ VC++ compiler -- MHS
01328     const Matrix &ret = elePtr->getInitialStiff();
01329 
01330   return 0;
01331 }
01332 
01333 
01334 int
01335 Domain::setRayleighDampingFactors(double alphaM, double betaK, double betaK0, double betaKc)
01336 {
01337   int result = 0;
01338   Element *elePtr;
01339   ElementIter &theElemIter = this->getElements();    
01340   while ((elePtr = theElemIter()) != 0) 
01341     result += elePtr->setRayleighDampingFactors(alphaM, betaK, betaK0, betaKc);
01342 
01343   Node *nodePtr;
01344   NodeIter &theNodeIter = this->getNodes();
01345   while ((nodePtr = theNodeIter()) != 0) {
01346     result += nodePtr->setRayleighDampingFactor(alphaM);
01347   }
01348 
01349   return result;
01350 }
01351 
01352 
01353 
01354 int
01355 Domain::commit(void)
01356 {
01357     // 
01358     // first invoke commit on all nodes and elements in the domain
01359     //
01360     Node *nodePtr;
01361     NodeIter &theNodeIter = this->getNodes();
01362     while ((nodePtr = theNodeIter()) != 0) {
01363       nodePtr->commitState();
01364     }
01365 
01366     Element *elePtr;
01367     ElementIter &theElemIter = this->getElements();    
01368     while ((elePtr = theElemIter()) != 0) {
01369       elePtr->commitState();
01370     }
01371 
01372     // set the new committed time in the domain
01373     committedTime = currentTime;
01374     dT = 0.0;
01375 
01376     // invoke record on all recorders
01377     for (int i=0; i<numRecorders; i++)
01378         theRecorders[i]->record(commitTag, currentTime);
01379 
01380     // update the commitTag
01381     commitTag++;
01382     return 0;
01383 }
01384 
01385 int
01386 Domain::revertToLastCommit(void)
01387 {
01388     // 
01389     // first invoke revertToLastCommit  on all nodes and elements in the domain
01390     //
01391     
01392     Node *nodePtr;
01393     NodeIter &theNodeIter = this->getNodes();
01394     while ((nodePtr = theNodeIter()) != 0)
01395         nodePtr->revertToLastCommit();
01396     
01397     Element *elePtr;
01398     ElementIter &theElemIter = this->getElements();    
01399     while ((elePtr = theElemIter()) != 0) {
01400         elePtr->revertToLastCommit();
01401     }
01402 
01403     // set the current time and load factor in the domain to last committed
01404     currentTime = committedTime;
01405     dT = 0.0;
01406 
01407     // apply load for the last committed time
01408     this->applyLoad(currentTime);
01409 
01410     return this->update();
01411 }
01412 
01413 int
01414 Domain::revertToStart(void)
01415 {
01416     // 
01417     // first invoke revertToLastCommit  on all nodes and 
01418     // elements in the domain
01419     //
01420     
01421     Node *nodePtr;
01422     NodeIter &theNodeIter = this->getNodes();
01423     while ((nodePtr = theNodeIter()) != 0) 
01424         nodePtr->revertToStart();
01425 
01426     Element *elePtr;
01427     ElementIter &theElements = this->getElements();    
01428     while ((elePtr = theElements()) != 0) {
01429         elePtr->revertToStart();
01430     }
01431 
01432 // ADDED BY TERJE //////////////////////////////////
01433     // invoke 'restart' on all recorders
01434     for (int i=0; i<numRecorders; i++) 
01435                 theRecorders[i]->restart();
01437 
01438     // set the current time and load factor in the domain to last committed
01439     committedTime = 0;
01440     currentTime = 0;
01441     dT = 0.0;
01442 
01443     // apply load for the last committed time
01444     this->applyLoad(currentTime);
01445 
01446     return this->update();
01447 }
01448 
01449 int
01450 Domain::update(void)
01451 {
01452   // set the global constants
01453   ops_Dt = dT;
01454   ops_TheActiveDomain = this;
01455 
01456   int ok = 0;
01457 
01458   // invoke update on all the ele's
01459   ElementIter &theEles = this->getElements();
01460   Element *theEle;
01461 
01462   while ((theEle = theEles()) != 0) {
01463     ok += theEle->update();
01464   }
01465 
01466   if (ok != 0)
01467     opserr << "Domain::update - domain failed in update\n";
01468 
01469   return ok;
01470 }
01471 
01472 
01473 int
01474 Domain::update(double newTime, double dT)
01475 {
01476   this->applyLoad(newTime);
01477   this->update();
01478 
01479   return 0;
01480 }
01481 
01482 
01483 
01484 int
01485 Domain::newStep(double dT)
01486 {
01487   return 0;
01488 }
01489 
01490 
01491 
01492 int
01493 Domain::setEigenvalues(const Vector &theValues)
01494 {
01495   // make sure the eigen value vector is large enough
01496   if (theEigenvalues == 0 || theEigenvalues->Size() != theValues.Size()) {
01497     
01498     // if not zero delete the old and create a new one
01499     if (theEigenvalues != 0)
01500       delete theEigenvalues;
01501 
01502     // create the new vector
01503     theEigenvalues = new Vector(theValues);
01504   } else
01505 
01506     // otherwise just a straight assignment
01507     *theEigenvalues = theValues;
01508 
01509 
01510   // now set the time at which eigen values were determined to be current domain time
01511   theEigenvalueSetTime = this->getCurrentTime();
01512 
01513   return 0;
01514 }
01515 
01516 
01517 const Vector &
01518 Domain::getEigenvalues(void) 
01519 {
01520   // ensure the eigen values were set
01521   if (theEigenvalues == 0) {
01522     opserr << "Domain::getEigenvalues - Eigenvalues were never set\n";
01523     exit(-1);
01524   }
01525 
01526   return *theEigenvalues;
01527 }  
01528 
01529 double 
01530 Domain::getTimeEigenvaluesSet(void) 
01531 {
01532   return theEigenvalueSetTime;
01533 }
01534 
01535 void
01536 Domain::setDomainChangeStamp(int newStamp)
01537 {
01538     currentGeoTag = newStamp;
01539 }
01540 
01541 
01542 void
01543 Domain::domainChange(void)
01544 {
01545     hasDomainChangedFlag = true;
01546 }
01547 
01548 
01549 int
01550 Domain::hasDomainChanged(void)
01551 {       
01552     // if the flag indicating the domain has changed since the
01553     // last call to this method has changed, increment the integer
01554     // and reset the flag
01555     bool result = hasDomainChangedFlag;
01556     hasDomainChangedFlag = false;
01557     if (result == true) {
01558         currentGeoTag++;
01559         nodeGraphBuiltFlag = false;
01560         eleGraphBuiltFlag = false;
01561     }
01562 
01563     // return the integer so user can determine if domain has changed 
01564     // since their last call to this method
01565     return currentGeoTag;
01566 }
01567 
01568 void
01569 Domain::Print(OPS_Stream &s, int flag) 
01570 {
01571 
01572   s << "Current Domain Information\n";
01573   s << "\tCurrent Time: " << currentTime;
01574   s << "\ntCommitted Time: " << committedTime << endln;
01575 
01576   s << "\nNODE DATA: NumNodes: " << theNodes->getNumComponents() << "\n";
01577   theNodes->Print(s, flag);
01578 
01579   s << "\nELEMENT DATA: NumEle: " << theElements->getNumComponents() << "\n";
01580   theElements->Print(s, flag);
01581   
01582   s << "\nSP_Constraints: numConstraints: ";
01583   s << theSPs->getNumComponents() << "\n";
01584   theSPs->Print(s, flag);
01585   
01586   s << "\nMP_Constraints: numConstraints: ";
01587   s << theMPs->getNumComponents() << "\n";
01588   theMPs->Print(s, flag);
01589 
01590   s << "\nLOAD PATTERNS: numPatterns: ";
01591   s << theLoadPatterns->getNumComponents() << "\n\n";
01592   theLoadPatterns->Print(s, flag);
01593 
01594   s << "\nPARAMETERS: numParameters: ";
01595   s << theParameters->getNumComponents() << "\n\n";
01596   theParameters->Print(s, flag);
01597 }
01598 
01599 OPS_Stream &operator<<(OPS_Stream &s, Domain &M)
01600 {
01601   M.Print(s);
01602   return s;
01603 }
01604 
01605 
01606 int
01607 Domain::addRecorder(Recorder &theRecorder)
01608 {
01609   if (theRecorder.setDomain(*this) != 0) {
01610     opserr << "Domain::addRecorder() - recorder could not be added\n";
01611     return -1;
01612   }
01613 
01614   Recorder **newRecorders = new Recorder *[numRecorders + 1]; 
01615   if (newRecorders == 0) {
01616     opserr << "Domain::addRecorder() - could not add ran out of memory\n";
01617     return -1;
01618   }
01619   
01620   for (int i=0; i<numRecorders; i++)
01621     newRecorders[i] = theRecorders[i];
01622   newRecorders[numRecorders] = &theRecorder;
01623   
01624   if (theRecorders != 0)
01625     delete [] theRecorders;
01626   
01627   theRecorders = newRecorders;
01628   numRecorders++;
01629   return 0;
01630 }
01631 
01632 
01633 int
01634 Domain::removeRecorders(void)
01635 {
01636     for (int i=0; i<numRecorders; i++)  
01637       delete theRecorders[i];
01638     
01639     if (theRecorders != 0) {
01640       delete [] theRecorders;
01641     }
01642   
01643     theRecorders = 0;
01644     numRecorders = 0;
01645     return 0;
01646 }
01647 
01648 int  
01649 Domain::addRegion(MeshRegion &theRegion)
01650 {
01651     MeshRegion **newRegions = new MeshRegion *[numRegions + 1]; 
01652     if (newRegions == 0) {
01653         opserr << "Domain::addRegion() - could not add ran out of memory\n";
01654         return -1;
01655     }
01656     
01657     for (int i=0; i<numRegions; i++)
01658         newRegions[i] = theRegions[i];
01659     newRegions[numRegions] = &theRegion;
01660     theRegion.setDomain(this);
01661     if (theRegions != 0)
01662       delete [] theRegions;
01663     
01664     theRegions = newRegions;
01665     numRegions++;
01666     return 0;
01667 }
01668 
01669 MeshRegion *
01670 Domain::getRegion(int tag)
01671 {
01672     for (int i=0; i<numRegions; i++)
01673       if (theRegions[i]->getTag() == tag)
01674         return theRegions[i];
01675 
01676     return 0;
01677 }
01678 
01679 
01680 int 
01681 Domain::buildEleGraph(Graph *theEleGraph)
01682 {
01683     int numVertex = this->getNumElements();
01684 
01685     // see if quick return
01686 
01687     if (numVertex == 0) 
01688         return 0;
01689 
01690     
01691     // create another vertices array which aids in adding edges
01692     
01693     int *theElementTagVertices = 0;
01694     int maxEleNum = 0;
01695     Element *elePtr;
01696     ElementIter &eleIter = this->getElements();
01697     while ((elePtr = eleIter()) != 0)
01698         if (elePtr->getTag() > maxEleNum)
01699             maxEleNum = elePtr->getTag();
01700 
01701     theElementTagVertices = new int[maxEleNum+1];
01702 
01703     if (theElementTagVertices == 0) {
01704         opserr << "WARNING Domain::buildEleGraph ";
01705         opserr << " - Not Enough Memory for ElementTagVertices\n";
01706         return -1;
01707     }
01708 
01709     for (int j=0; j<=maxEleNum; j++) theElementTagVertices[j] = -1;
01710     opserr << "Domain::buildEleGraph numVertex maxEleNum " << numVertex << " " << maxEleNum << endln;
01711     // now create the vertices with a reference equal to the element number.
01712     // and a tag which ranges from 0 through numVertex-1
01713 
01714     ElementIter &eleIter2 = this->getElements();
01715     int count = START_VERTEX_NUM;
01716     while ((elePtr = eleIter2()) != 0) {
01717         int ElementTag = elePtr->getTag();
01718         Vertex *vertexPtr = new Vertex(count,ElementTag);
01719 
01720         if (vertexPtr == 0) {
01721             opserr << "WARNING Domain::buildEleGraph";
01722             opserr << " - Not Enough Memory to create ";
01723             opserr << count << "th Vertex\n";
01724             delete [] theElementTagVertices;
01725             return -1;
01726         }
01727 
01728         theEleGraph->addVertex(vertexPtr);
01729         theElementTagVertices[ElementTag] = count++;
01730         
01731     }
01732 
01733     // We now need to determine which elements are asssociated with each node.
01734     // As this info is not in the Node interface we must build it; which we
01735     // do using vertices for each node, when we addVertex at thes nodes we
01736     // will not be adding vertices but element tags.
01737 
01738     Vertex **theNodeTagVertices = 0;
01739     int maxNodNum = 0;
01740     Node *nodPtr;
01741     NodeIter &nodeIter = this->getNodes();
01742     while ((nodPtr = nodeIter()) != 0)
01743         if (nodPtr->getTag() > maxNodNum)
01744             maxNodNum = nodPtr->getTag();
01745 
01746     theNodeTagVertices = new Vertex *[maxNodNum+1];
01747 
01748     if (theNodeTagVertices == 0) {
01749         opserr << "WARNING Domain::buildEleGraph ";
01750         opserr << " - Not Enough Memory for NodeTagVertices\n";
01751         return -1;
01752     }
01753     
01754     for (int l=0; l<=maxNodNum; l++) theNodeTagVertices[l] = 0;
01755 
01756     // now create the vertices with a reference equal to the node number.
01757     // and a tag which ranges from 0 through numVertex-1 and placed in
01758     // theNodeTagVertices at a position equal to the node's tag.
01759 
01760     NodeIter &nodeIter2 = this->getNodes();
01761     count = START_VERTEX_NUM;
01762     while ((nodPtr = nodeIter2()) != 0) {
01763         int nodeTag = nodPtr->getTag();
01764         Vertex *vertexPtr = new Vertex(count++,nodeTag);
01765         theNodeTagVertices[nodeTag] = vertexPtr;
01766 
01767         if (vertexPtr == 0) {
01768             opserr << "WARNING Domain::buildEleGraph";
01769             opserr << " - Not Enough Memory to create ";
01770             opserr << count << "th Node Vertex\n";
01771             delete [] theNodeTagVertices;
01772             return -1;
01773         }
01774     }
01775 
01776     // now add the the Elements to the nodes
01777 
01778     ElementIter &eleIter3 = this->getElements();
01779 
01780     while((elePtr = eleIter3()) != 0) {
01781         int eleTag = elePtr->getTag();
01782         const ID &id = elePtr->getExternalNodes();
01783 
01784         int size = id.Size();
01785         for (int i=0; i<size; i++) 
01786             theNodeTagVertices[id(i)]->addEdge(eleTag);
01787     }
01788 
01789 
01790 
01791     // now add the edges to the vertices of our element graph;
01792     // this is done by looping over the Node vertices, getting their 
01793     // Adjacenecy and adding edges between elements with common nodes
01794 
01795 
01796     Vertex *vertexPtr;
01797     for (int k=0; k<=maxNodNum; k++)
01798         if ((vertexPtr = theNodeTagVertices[k]) != 0) {
01799 
01800             const ID &id = vertexPtr->getAdjacency();
01801 
01802             int size = id.Size();
01803             for (int i=0; i<size; i++) {
01804                 int Element1 = id(i);
01805 
01806                 int vertexTag1 = theElementTagVertices[Element1];
01807 
01808                 for (int j=0; j<size; j++) 
01809                     if (i != j) {
01810 
01811                         int Element2 = id(j);
01812                         int vertexTag2 = theElementTagVertices[Element2];
01813 
01814                         // addEdge() adds for both vertices - do only once
01815 
01816 
01817                         if (vertexTag1 > vertexTag2) 
01818                             theEleGraph->addEdge(vertexTag1,vertexTag2);
01819                             theEleGraph->addEdge(vertexTag2,vertexTag1);                        
01820                     }
01821             }
01822         }
01823 
01824     // done now delete theElementTagVertices, the node Vertices and
01825     // theNodeTagVertices
01826    
01827     delete [] theElementTagVertices;    
01828     
01829     for (int i=0; i<=maxNodNum; i++)
01830         if ((vertexPtr = theNodeTagVertices[i]) != 0) 
01831             delete vertexPtr;
01832             
01833     delete [] theNodeTagVertices;
01834     
01835     return 0;
01836     
01837 }
01838 
01839 int 
01840 Domain::buildNodeGraph(Graph *theNodeGraph)
01841 {
01842     int numVertex = this->getNumNodes();
01843 
01844     if (numVertex == 0) {
01845         return 0;
01846     }   
01847         
01848     // create another vertices array which aids in adding edges
01849     
01850     int *theNodeTagVertices = 0;
01851     int maxNodNum = 0;
01852     Node *nodPtr;
01853     NodeIter &nodeIter = this->getNodes();
01854     while ((nodPtr = nodeIter()) != 0)
01855         if (nodPtr->getTag() > maxNodNum)
01856             maxNodNum = nodPtr->getTag();
01857 
01858     theNodeTagVertices = new int [maxNodNum+1];
01859 
01860     if (theNodeTagVertices == 0) {
01861         opserr << "WARNING Domain::buildNodeGraph ";
01862         opserr << " - Not Enough Memory for NodeTagVertices\n";
01863         return -1;
01864     }
01865     
01866     for (int j=0; j<=maxNodNum; j++) theNodeTagVertices[j] = -1;
01867 
01868     // now create the vertices with a reference equal to the node number.
01869     // and a tag which ranges from START_VERTEX_NUM through 
01870     // numNodes+START_VERTEX_NUM
01871 
01872     NodeIter &nodeIter2 = this->getNodes();
01873     int count = START_VERTEX_NUM;
01874     while ((nodPtr = nodeIter2()) != 0) {
01875         int nodeTag = nodPtr->getTag();
01876         Vertex *vertexPtr = new Vertex(count,nodeTag);
01877 
01878         if (vertexPtr == 0) {
01879             opserr << "WARNING Domain::buildNodeGraph";
01880             opserr << " - Not Enough Memory to create ";
01881             opserr << count << "th Vertex\n";
01882             delete [] theNodeTagVertices;
01883             return -1;
01884         }
01885 
01886         // add the vertex to the graph
01887         theNodeGraph->addVertex(vertexPtr);
01888         theNodeTagVertices[nodeTag] = count++;
01889     }
01890 
01891     // now add the edges, by looping over the Elements, getting their
01892     // IDs and adding edges between all elements who share a node.
01893     
01894     Element *elePtr;
01895     ElementIter &eleIter = this->getElements();
01896 
01897     while((elePtr = eleIter()) != 0) {
01898         const ID &id = elePtr->getExternalNodes();
01899 
01900         int size = id.Size();
01901         for (int i=0; i<size; i++) {
01902             int node1 = id(i);
01903             int vertexTag1 = theNodeTagVertices[node1];
01904             
01905             for (int j=0; j<size; j++) 
01906                 if (i != j) {
01907 
01908                     int node2 = id(j);
01909                     int vertexTag2 = theNodeTagVertices[node2];
01910                     
01911                     // addEdge() adds for both vertices - do only once
01912                     if (vertexTag1 > vertexTag2) 
01913                         theNodeGraph->addEdge(vertexTag1,vertexTag2);
01914                 }
01915         }
01916     }
01917 
01918     // done now delete theNodeTagVertices
01919     delete [] theNodeTagVertices;
01920     
01921     return 0;
01922 }
01923 
01924 
01925 int 
01926 Domain::sendSelf(int cTag, Channel &theChannel)
01927 {
01928   // update the commitTag and currentGeoTag
01929   commitTag = cTag;
01930 
01931   this->hasDomainChanged();
01932 
01933   // first we send info about the current domain flag and the number of
01934   // elements, nodes, constraints and load patterns currently in the domain
01935   int numEle, numNod, numSPs, numMPs, numLPs, numParam;
01936   numNod = theNodes->getNumComponents();
01937   numEle = theElements->getNumComponents();
01938   numSPs = theSPs->getNumComponents();
01939   numMPs = theMPs->getNumComponents();  
01940   numLPs = theLoadPatterns->getNumComponents();
01941   numParam = theParameters->getNumComponents();
01942 
01943   ID domainData(13);
01944   domainData(0) = currentGeoTag;
01945 
01946   domainData(1) = numNod;
01947   domainData(2) = numEle;
01948   domainData(3) = numSPs;
01949   domainData(4) = numMPs;
01950   domainData(5) = numLPs;
01951   domainData(11) = numParam;
01952 
01953   // add the database tag for the ID's storing node, element, constraints
01954   // and loadpattern data into domainData
01955   // NOTE: if these still 0 get new ones from the channel
01956   if (dbNod == 0) {
01957     dbNod = theChannel.getDbTag();
01958     dbEle = theChannel.getDbTag();
01959     dbSPs = theChannel.getDbTag();
01960     dbMPs = theChannel.getDbTag();
01961     dbLPs = theChannel.getDbTag();
01962     dbParam = theChannel.getDbTag();
01963   } 
01964 
01965   domainData(6) = dbNod;
01966   domainData(7) = dbEle;
01967   domainData(8) = dbSPs;
01968   domainData(9) = dbMPs;
01969   domainData(10) = dbLPs;
01970   domainData(12) = dbParam;
01971 
01972   if (theChannel.sendID(theDbTag, commitTag, domainData) < 0) {
01973     opserr << "Domain::send - channel failed to send the initial ID\n";
01974     return -1;
01975   }    
01976 
01977   // send the time information
01978   Vector domainTime(1);
01979   domainTime(0) = committedTime;
01980 
01981   if (theChannel.sendVector(theDbTag, commitTag, domainTime) < 0) {
01982     opserr << "Domain::send - channel failed to send the time Vector\n";
01983     return -2;
01984   }    
01985 
01986   // now check if data defining the objects in the domain needs to be sent 
01987   // NOTE THIS APPROACH MAY NEED TO CHANGE FOR VERY LARGE PROBLEMS IF CHANNEL CANNOT
01988   // HANDLE VERY LARGE ID OBJECTS.
01989 
01990   /*
01991   if (theChannel.isDatastore() == 1) {
01992     static ID theLastSendTag(1);
01993     if (theChannel.recvID(0,0,theLastSendTag) == 0)
01994       lastGeoSendTag = theLastSendTag(0);
01995     else
01996       lastGeoSendTag = -1;
01997   }
01998   */
01999 
02000   if (lastChannel != theChannel.getTag() || lastGeoSendTag != currentGeoTag) {
02001 
02002     lastChannel = theChannel.getTag();
02003     
02004     //
02005     // into an ID we are gonna place the class and db tags for each node so can rebuild
02006     // this ID we then send to the channel
02007     //
02008 
02009     // create the ID and get the node iter
02010     if (numNod != 0) {
02011       ID nodeData(numNod*2);
02012       Node *theNode;
02013       NodeIter &theNodes = this->getNodes();
02014       int loc =0;
02015 
02016       // loop over nodes in domain adding their classTag and dbTag to the ID
02017       while ((theNode = theNodes()) != 0) {
02018         nodeData(loc) = theNode->getClassTag();
02019         int dbTag = theNode->getDbTag();
02020         
02021         // if dbTag still 0 get one from Channel; 
02022         // if this tag != 0 set the dbTag in node
02023         if (dbTag == 0) {// go get a new tag and setDbTag in ele if this not 0 
02024           dbTag = theChannel.getDbTag();
02025           if (dbTag != 0)
02026             theNode->setDbTag(dbTag);
02027         }
02028       
02029         nodeData(loc+1) = dbTag;
02030         loc+=2;
02031       }    
02032 
02033       // now send the ID
02034       if (theChannel.sendID(dbNod, currentGeoTag, nodeData) < 0) {
02035         opserr << "Domain::send - channel failed to send the node ID\n";
02036         return -2;
02037       }
02038     }
02039 
02040     // we do the same for elements as we did for nodes above .. see comments
02041     // for nodes if you can't figure whats going on!
02042 
02043     if (numEle != 0) {
02044       ID elementData(numEle*2);
02045       Element *theEle;
02046       ElementIter &theElements = this->getElements();
02047       int loc = 0;
02048     
02049       while ((theEle = theElements()) != 0) {
02050         elementData(loc) = theEle->getClassTag();
02051         int dbTag = theEle->getDbTag();
02052 
02053         if (dbTag == 0) {// go get a new tag and setDbTag in ele if this not 0 
02054           dbTag = theChannel.getDbTag();
02055           if (dbTag != 0)
02056             theEle->setDbTag(dbTag);
02057         }
02058       
02059         elementData(loc+1) = dbTag;
02060         loc+=2;
02061       }
02062 
02063       // now send the ID
02064       if (theChannel.sendID(dbEle, currentGeoTag, elementData) < 0) {
02065         opserr << "Domain::send - channel failed to send the element ID\n";
02066         return -3;
02067       }
02068     }
02069 
02070     // we do the same for SP_Constraints as for Nodes above .. see comments
02071     // for nodes if you can't figure whats going on!    
02072     
02073     if (numSPs != 0) {
02074       ID spData(numSPs*2);
02075       SP_Constraint *theSP;
02076       SP_ConstraintIter &theSPs = this->getSPs();
02077       int loc = 0;
02078     
02079       while ((theSP = theSPs()) != 0) {
02080         spData(loc) = theSP->getClassTag();
02081         int dbTag = theSP->getDbTag();
02082 
02083         if (dbTag == 0) {// go get a new tag and setDbTag in ele if this not 0 
02084           dbTag = theChannel.getDbTag();
02085           if (dbTag != 0)
02086             theSP->setDbTag(dbTag);
02087         }
02088         
02089         spData(loc+1) = dbTag;
02090         loc+=2;
02091       }    
02092 
02093       if (theChannel.sendID(dbSPs, currentGeoTag, spData) < 0) {
02094         opserr << "Domain::send - channel failed to send the SP_Constraint ID\n";
02095         return -4;
02096       }
02097     }
02098 
02099     // we do the same for MP_Constraints as for Nodes above .. see comments
02100     // for nodes if you can't figure whats going on!    
02101     
02102     if (numMPs != 0) {
02103       ID mpData(numMPs*2);
02104       MP_Constraint *theMP;
02105       MP_ConstraintIter &theMPs = this->getMPs();
02106       int loc = 0;
02107     
02108       while ((theMP = theMPs()) != 0) {
02109         mpData(loc) = theMP->getClassTag();
02110         int dbTag = theMP->getDbTag();
02111         
02112         if (dbTag == 0) {// go get a new tag and setDbTag in ele if this not 0 
02113           dbTag = theChannel.getDbTag();
02114           if (dbTag != 0)
02115             theMP->setDbTag(dbTag);
02116         }
02117       
02118         mpData(loc+1) = dbTag;
02119         loc+=2;
02120       }    
02121 
02122       if (theChannel.sendID(dbMPs, currentGeoTag, mpData) < 0) {
02123         opserr << "Domain::send - channel failed to send the MP_Constraint ID\n";
02124         return -5;
02125       }
02126     }
02127 
02128     // we do the same for LoadPatterns as we did for Nodes above .. see comments
02129     // for nodes if you can't figure whats going on!    
02130 
02131     if (numLPs != 0) {
02132       ID lpData(numLPs*2);
02133       LoadPattern *theLP;
02134       LoadPatternIter &theLPs = this->getLoadPatterns();
02135       int loc = 0;
02136     
02137       while ((theLP = theLPs()) != 0) {
02138         lpData(loc) = theLP->getClassTag();
02139         int dbTag = theLP->getDbTag();
02140 
02141         if (dbTag == 0) {// go get a new tag and setDbTag in ele if this not 0 
02142           dbTag = theChannel.getDbTag();
02143           if (dbTag != 0)
02144             theLP->setDbTag(dbTag);
02145         }
02146       
02147         lpData(loc+1) = dbTag;
02148         loc+=2;
02149       }    
02150 
02151       if (theChannel.sendID(dbLPs, currentGeoTag, lpData) < 0) {
02152         opserr << "Domain::send - channel failed to send the LoadPattern ID\n";
02153         return -6;
02154       }    
02155     }
02156 
02157 
02158     // now so that we don't do this next time if nothing in the domain has changed
02159     lastGeoSendTag = currentGeoTag;
02160     /*
02161     if (theChannel.isDatastore() == 1) {
02162       static ID theLastSendTag(1);
02163       theLastSendTag(0) = lastGeoSendTag;
02164       theChannel.sendID(0,0, theLastSendTag);
02165     }
02166     */
02167   }
02168 
02169   //
02170   // now we invoke sendSelf on each of the objects .. 
02171   // NOTE: don't have to set the dbTags of the objects as just done this above
02172   //
02173 
02174   // send the nodes
02175   Node *theNode;
02176   NodeIter &theNodes = this->getNodes();
02177   while ((theNode = theNodes()) != 0) {
02178     if (theNode->sendSelf(commitTag, theChannel) < 0) {
02179       opserr << "Domain::send - node with tag " << theNode->getTag() << " failed in sendSelf\n";
02180       return -7;
02181     }
02182   }
02183 
02184   // send the elements
02185   Element *theEle;
02186   ElementIter &theElements = this->getElements();
02187   while ((theEle = theElements()) != 0) {
02188     if (theEle->sendSelf(commitTag, theChannel) < 0) {
02189       opserr << "Domain::send - element with tag " << theEle->getTag() << " failed in sendSelf\n";
02190       return -8;
02191     }
02192   }
02193 
02194   // send the single point constraints
02195   SP_Constraint *theSP;
02196   SP_ConstraintIter &theSPs = this->getSPs();
02197   while ((theSP = theSPs()) != 0) {
02198     if (theSP->sendSelf(commitTag, theChannel) < 0) {
02199       opserr << "Domain::send - SP_Constraint with tag " << theSP->getTag() << " failed in sendSelf\n";
02200       return -9;
02201     }
02202   }    
02203 
02204   // send the multi point constraints
02205   MP_Constraint *theMP;
02206   MP_ConstraintIter &theMPs = this->getMPs();
02207   while ((theMP = theMPs()) != 0) {
02208     if (theMP->sendSelf(commitTag, theChannel) < 0) {
02209       opserr << "Domain::send - MP_Constraint with tag " << theMP->getTag() << " failed in sendSelf\n";
02210       return -10;
02211     }
02212   }    
02213 
02214   // send the load patterns
02215   LoadPattern *theLP;
02216   LoadPatternIter &theLPs = this->getLoadPatterns();
02217   while ((theLP = theLPs()) != 0) {
02218     if (theLP->sendSelf(commitTag, theChannel) < 0) {
02219       opserr << "Domain::send - LoadPattern with tag " << theLP->getTag() << " failed in sendSelf\n";
02220       return -11;
02221     }
02222   }  
02223 
02224   // if get here we were successfull
02225   return commitTag;
02226 }
02227 
02228 
02229 int 
02230 Domain::recvSelf(int cTag, Channel &theChannel, FEM_ObjectBroker &theBroker) 
02231 {
02232   // set the commitTag in the domain to cTag & update the getTag if needed
02233   commitTag = cTag;
02234   this->hasDomainChanged();
02235 
02236   // first we get the data about the state of the domain for this commitTag
02237   ID domainData(11);
02238   if (theChannel.recvID(theDbTag, commitTag, domainData) < 0) {
02239     opserr << "Domain::recv - channel failed to recv the initial ID\n";
02240     return -1;
02241   }
02242 
02243   // recv the time information
02244   Vector domainTime(1);
02245   if (theChannel.recvVector(theDbTag, commitTag, domainTime) < 0) {
02246     opserr << "Domain::send - channel failed to recv thetime Vector\n";
02247     return -1;
02248   }    
02249 
02250   currentTime = domainTime(0);
02251   committedTime = currentTime;
02252 
02253   // 
02254   // now if the currentGeoTag does not agree with whats in the domain
02255   // we must wipe everything in the domain and recreate the domain based on the info from the channel
02256   //
02257 
02258   /*
02259   if (theChannel.isDatastore() == 1) {
02260     static ID theLastSendTag(1);
02261     if (theChannel.recvID(0,0,theLastSendTag) == 0)
02262       lastGeoSendTag = theLastSendTag(0);
02263   }
02264   */
02265 
02266   if (currentGeoTag == 0 || lastChannel != theChannel.getTag() || domainData(0) != currentGeoTag) {
02267 
02268     lastChannel = theChannel.getTag();
02269     
02270     // set the currrentGeoTag
02271     int geoTag = domainData(0);
02272 
02273     int i, loc;
02274     int numEle, numNod, numSPs, numMPs, numLPs;
02275 
02276     // if receiving set lastGeoSendTag to be equal to currentGeoTag 
02277     // at time all the data was sent if not we must clear out the objects and rebuild
02278     lastGeoSendTag = domainData(0);
02279 
02280     // clear out the all the components in the current domain
02281     this->clearAll();
02282 
02283     currentTime = domainTime(0);
02284     committedTime = currentTime;
02285 
02286     // 
02287     // now we rebuild the nodes
02288     //
02289     
02290     // first get the information from the domainData about the nodes
02291     numNod = domainData(1);
02292     dbNod = domainData(6);
02293     
02294     if (numNod != 0) {
02295       ID nodeData(2*numNod);
02296 
02297       // now receive the ID about the nodes, class tag and dbTags
02298       if (theChannel.recvID(dbNod, geoTag, nodeData) < 0) {
02299         opserr << "Domain::recv - channel failed to recv the node ID\n";
02300         return -2;
02301       }
02302 
02303       // now for each node we 1) get a new node of the correct type from the ObjectBroker
02304       // 2) ensure the node exists and set it's dbTag, 3) we invoke recvSelf on this new 
02305       // blank node and 4) add this node to the domain
02306       loc = 0;
02307       for (i=0; i<numNod; i++) {
02308         int classTag = nodeData(loc);
02309         int dbTag = nodeData(loc+1);
02310       
02311         Node *theNode = theBroker.getNewNode(classTag);
02312 
02313         if (theNode == 0) {
02314           opserr << "Domain::recv - cannot create node with classTag " << classTag << endln;
02315           return -2;
02316         }                       
02317 
02318         theNode->setDbTag(dbTag);
02319       
02320         if (theNode->recvSelf(commitTag, theChannel, theBroker) < 0) {
02321           opserr << "Domain::recv - node with dbTag " << dbTag << " failed in recvSelf\n";
02322           return -2;
02323         }                       
02324 
02325         if (this->addNode(theNode) == false) {
02326           opserr << "Domain::recv - could not add node with tag " << theNode->getTag() << " into domain\n!";
02327           return -3;
02328         }                       
02329 
02330         loc+=2;
02331       }
02332     }
02333 
02334     // 
02335     // now we rebuild the elements .. same as nodes above .. see above if can't understand!!
02336     //
02337     
02338     numEle = domainData(2);
02339     dbEle = domainData(7);
02340 
02341     if (numEle != 0) {
02342       ID eleData(2*numEle);
02343 
02344       if (theChannel.recvID(dbEle, geoTag, eleData) < 0) {
02345         opserr << "Domain::recv - channel failed to recv the Ele ID\n";
02346         return -2;
02347       }
02348 
02349       loc = 0;
02350       for (i=0; i<numEle; i++) {
02351         int classTag = eleData(loc);
02352         int dbTag = eleData(loc+1);
02353       
02354         Element *theEle = theBroker.getNewElement(classTag);
02355         if (theEle == 0) {
02356           opserr << "Domain::recv - cannot create element with classTag " << classTag << endln;
02357           return -2;
02358         }                       
02359         theEle->setDbTag(dbTag);
02360       
02361         if (theEle->recvSelf(commitTag, theChannel, theBroker) < 0) {
02362           opserr << "Domain::recv - Ele with dbTag " << dbTag << " failed in recvSelf()\n";
02363           return -2;
02364         }                       
02365 
02366         if (this->addElement(theEle) == false) {
02367           opserr << "Domain::recv - could not add Ele with tag " << theEle->getTag() << " into domain!\n";
02368           return -3;
02369         }                       
02370 
02371         loc+=2;
02372       }
02373     }
02374 
02375     // 
02376     // now we rebuild the SP_Constraints .. same as nodes above .. see above if can't understand!!
02377     //
02378     
02379     numSPs = domainData(3);
02380     dbSPs = domainData(8);
02381     if (numSPs != 0) {
02382       ID spData(2*numSPs);
02383 
02384       if (theChannel.recvID(dbSPs, geoTag, spData) < 0) {
02385         opserr << "Domain::recv - channel failed to recv the SP_Constraints ID\n";
02386         return -2;
02387       }
02388 
02389       loc = 0;
02390       for (i=0; i<numSPs; i++) {
02391         int classTag = spData(loc);
02392         int dbTag = spData(loc+1);
02393       
02394         SP_Constraint *theSP = theBroker.getNewSP(classTag);
02395         if (theSP == 0) {
02396           opserr << "Domain::recv - cannot create SP_Constraint with classTag " << classTag << endln;
02397           return -2;
02398         }                       
02399         theSP->setDbTag(dbTag);
02400       
02401         if (theSP->recvSelf(commitTag, theChannel, theBroker) < 0) {
02402           opserr << "Domain::recv - SP_Constraint with dbTag " << dbTag << " failed in recvSelf\n";
02403           return -2;
02404         }                       
02405 
02406         if (this->addSP_Constraint(theSP) == false) {
02407           opserr << "Domain::recv - could not add SP_Constraint with tag " << theSP->getTag() << " into domain!\n";
02408           return -3;
02409         }                       
02410 
02411         loc+=2;
02412       }
02413     }
02414 
02415 
02416     // 
02417     // now we rebuild the MP_Constraints .. same as nodes above .. see above if can't understand!!
02418     //
02419     
02420     numMPs = domainData(4);
02421     dbMPs = domainData(9);
02422 
02423     if (numMPs != 0) {
02424       ID mpData(2*numMPs);
02425 
02426       if (theChannel.recvID(dbMPs, geoTag, mpData) < 0) {
02427         opserr << "Domain::recv - channel failed to recv the MP_Constraints ID\n";
02428         return -2;
02429       }
02430 
02431       loc = 0;
02432       for (i=0; i<numMPs; i++) {
02433         int classTag = mpData(loc);
02434         int dbTag = mpData(loc+1);
02435       
02436         MP_Constraint *theMP = theBroker.getNewMP(classTag);
02437         if (theMP == 0) {
02438           opserr << "Domain::recv - cannot create MP_Constraint with classTag " << classTag << endln;
02439           return -2;
02440         }                       
02441         theMP->setDbTag(dbTag);
02442       
02443         if (theMP->recvSelf(commitTag, theChannel, theBroker) < 0) {
02444           opserr << "Domain::recv - MP_Constraint with dbTag " << dbTag << " failed in recvSelf\n";
02445           return -2;
02446         }                       
02447 
02448         if (this->addMP_Constraint(theMP) == false) {
02449           opserr << "Domain::recv - could not add MP_Constraint with tag " << theMP->getTag() << " into domain!\n";
02450           return -3;
02451         }                       
02452         
02453         loc+=2;
02454       }
02455     }
02456 
02457     // 
02458     // now we rebuild the LoadPatterns .. same as nodes above .. see above if can't understand!!
02459     //
02460     
02461     numLPs = domainData(5);
02462     dbLPs = domainData(10);
02463 
02464     if (numLPs != 0) {
02465       ID lpData(2*numLPs);
02466       
02467       if (theChannel.recvID(dbLPs, geoTag, lpData) < 0) {
02468         opserr << "Domain::recv - channel failed to recv the MP_Constraints ID\n";
02469         return -2;
02470       }
02471 
02472       loc = 0;
02473       for (i=0; i<numLPs; i++) {
02474         int classTag = lpData(loc);
02475         int dbTag = lpData(loc+1);
02476 
02477         LoadPattern *theLP = theBroker.getNewLoadPattern(classTag);
02478         if (theLP == 0) {
02479           opserr << "Domain::recv - cannot create MP_Constraint with classTag  " << classTag << endln;
02480           return -2;
02481         }                       
02482         theLP->setDbTag(dbTag);
02483       
02484         if (theLP->recvSelf(commitTag, theChannel, theBroker) < 0) {
02485           opserr << "Domain::recv - LoadPattern with dbTag " << dbTag << " failed in recvSelf\n";
02486           return -2;
02487         }                       
02488 
02489         if (this->addLoadPattern(theLP) == false) {
02490           opserr << "Domain::recv - could not add LoadPattern with tag " << theLP->getTag() <<  " into the Domain\n";
02491           return -3;
02492         }                       
02493 
02494         loc+=2;
02495       }
02496     }
02497 
02498     // set the currentGeoTag & mark domainChangeFlag as false
02499     // this way if restoring froma a database and domain has not changed for the analysis
02500     // the analysis will not have to to do a domainChanged() operation
02501     currentGeoTag = domainData(0);
02502 
02503     lastGeoSendTag = currentGeoTag;
02504     hasDomainChangedFlag = false;
02505 
02506   } else {
02507 
02508     // in this block .. we have the components they just have to recv themselves again
02509     
02510     Node *theNode;
02511     NodeIter &theNodes = this->getNodes();
02512     while ((theNode = theNodes()) != 0) {
02513       if (theNode->recvSelf(commitTag, theChannel, theBroker) < 0) {
02514         opserr << "Domain::recv - node with tag " << theNode->getTag() << " failed in recvSelf\n";
02515         return -7;
02516       }
02517     }
02518 
02519     Element *theEle;
02520     ElementIter &theElements = this->getElements();
02521     while ((theEle = theElements()) != 0) {
02522       if (theEle->recvSelf(commitTag, theChannel, theBroker) < 0) {
02523         opserr << "Domain::recv - element with tag " << theEle->getTag() <<  " failed in recvSelf\n";
02524         return -8;
02525       }
02526       theEle->update();
02527     }
02528 
02529     SP_Constraint *theSP;
02530     SP_ConstraintIter &theSPs = this->getSPs();
02531     while ((theSP = theSPs()) != 0) {
02532       if (theSP->recvSelf(commitTag, theChannel, theBroker) < 0) {
02533         opserr << "Domain::recv - SP_Constraint with tag " << theSP->getTag() << " failed in recvSelf\n";
02534         return -9;
02535       }
02536     }    
02537 
02538     MP_Constraint *theMP;
02539     MP_ConstraintIter &theMPs = this->getMPs();
02540     while ((theMP = theMPs()) != 0) {
02541       if (theMP->recvSelf(commitTag, theChannel, theBroker) < 0) {
02542         opserr << "Domain::recv - MP_Constraint with tag " << theMP->getTag() << " failed in recvSelf\n";
02543         return -10;
02544       }
02545     }    
02546 
02547     LoadPattern *theLP;
02548     LoadPatternIter &theLPs = this->getLoadPatterns();
02549     while ((theLP = theLPs()) != 0) {
02550       if (theLP->recvSelf(commitTag, theChannel, theBroker) < 0) {
02551         opserr << "Domain::recv - LoadPattern with tag" << theLP->getTag() << " failed in recvSelf";
02552         return -11;
02553       }
02554     }  
02555   } 
02556 
02557   // now set the domains lastGeoSendTag and currentDomainChangedFlag
02558   lastGeoSendTag = currentGeoTag;  
02559 
02560   // if get here we were successfull
02561   return 0;
02562 }
02563 
02564 
02565 double
02566 Domain::getNodeDisp(int nodeTag, int dof, int &errorFlag)
02567 {
02568   double result = 0.0;
02569   errorFlag = 0;
02570   Node *theNode = this->getNode(nodeTag);
02571   if (theNode == 0) {
02572     errorFlag = -1;
02573     return 0.0;
02574   }
02575   const Vector &disp = theNode->getTrialDisp();
02576   if (dof < disp.Size() && dof >= 0) {
02577     result = disp(dof); 
02578   }  
02579   
02580   return result;
02581 }
02582 
02583 int 
02584 Domain::setMass(const Matrix &mass, int nodeTag)
02585 {
02586   int result = 0;
02587   Node *theNode = this->getNode(nodeTag);
02588   if (theNode == 0) {
02589     return -1;
02590   }
02591   return theNode->setMass(mass);  
02592 }
02593 
02594 int
02595 Domain::calculateNodalReactions(bool inclInertia)
02596 {
02597   Node *theNode;
02598   Element *theElement;
02599 
02600   NodeIter &theNodes = this->getNodes();
02601   while ((theNode = theNodes()) != 0) {
02602     theNode->resetReactionForce(inclInertia);
02603   }
02604 
02605   ElementIter &theElements = this->getElements();
02606   while ((theElement = theElements()) != 0)
02607     theElement->addResistingForceToNodalReaction(inclInertia);
02608   return 0;
02609 }

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