MeshRegion.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.4 $
00022 // $Date: 2003/02/14 23:01:02 $
00023 // $Source: /usr/local/cvs/OpenSees/SRC/domain/region/MeshRegion.cpp,v $
00024                                                                         
00025                                                                         
00026 // Written: fmk 
00027 //
00028 // Description: This file contains the class definition for MeshRegion.
00029 // A MeshRegion is a part of the domain which is defined by a set of
00030 // Elements and Nodes (all the end nodes of the elements are in the region, 
00031 // as are all elements whose end nodes are in the region)
00032 //
00033 // What: "@(#) MeshRegion.h, revA"
00034 
00035 
00036 #include <MeshRegion.h>
00037 #include <stdlib.h>
00038 #include <string.h>
00039 
00040 #include <Element.h>
00041 #include <Node.h>
00042 #include <ID.h>
00043 #include <Domain.h>
00044 #include <NodeRecorder.h>
00045 #include <ElementRecorder.h>
00046 #include <NodeIter.h>
00047 #include <ElementIter.h>
00048 #include <Channel.h>
00049 #include <FEM_ObjectBroker.h>
00050 
00051 MeshRegion::MeshRegion(int tag) 
00052   :DomainComponent(tag, REGION_TAG_MeshRegion), 
00053   alphaM(0), betaK(0), betaK0(0), betaKc(0),
00054   theNodes(0), theElements(0),
00055   currentGeoTag(0), lastGeoSendTag(-1), dbNod(0), dbEle(0)
00056 {
00057     // does nothing
00058 }
00059 
00060 MeshRegion::MeshRegion(int tag, int cTag) 
00061   :DomainComponent(tag, cTag), alphaM(0), betaK(0), betaK0(0), betaKc(0),
00062   theNodes(0), theElements(0),
00063   currentGeoTag(0), lastGeoSendTag(-1), dbNod(0), dbEle(0)
00064 {
00065     // does nothing
00066 }
00067 
00068 
00069 MeshRegion::~MeshRegion() 
00070 {
00071   if (theNodes != 0)
00072     delete theNodes;
00073   if (theElements != 0)
00074     delete theElements;
00075 }
00076 
00077 int 
00078 MeshRegion::setNodes(const ID &theNods)
00079 {
00080   // destroy the old lists
00081   if (theNodes != 0)
00082     delete theNodes;
00083   if (theElements != 0)
00084     delete theElements;
00085 
00086   //
00087   // create new element & node lists
00088   //
00089 
00090   // create empty lists
00091   Domain *theDomain = this->getDomain();
00092   if (theDomain == 0) {
00093     opserr << "MeshRegion::setNodes() - no domain yet set\n";
00094     return -1;
00095   }
00096 
00097   int numNodes = theNods.Size();
00098   theNodes = new ID(0, numNodes);
00099   theElements = new ID(0, numNodes);
00100   if (theNodes == 0 || theElements == 0) {
00101     opserr << "MeshRegion::setElements() - ran out of memory\n";
00102     return -1;
00103   }
00104 
00105   // add nodes to the node list if in the domain
00106   int loc = 0;
00107   for (int i=0; i<numNodes; i++) {
00108     int nodeTag = theNods(i);
00109     Node *theNode = theDomain->getNode(nodeTag);
00110     if (theNode != 0) {
00111       if (theNodes->getLocation(nodeTag) < 0)
00112         (*theNodes)[loc++] = nodeTag;      
00113     }
00114   }
00115 
00116   // now loop over the ele to create the ele list
00117   // NOTE - ele added to list if all it's nodes are in the region
00118   loc = 0;
00119 
00120   ElementIter &theEles = theDomain->getElements();
00121   Element *theEle;
00122 
00123   // loop over all ele
00124   while ((theEle = theEles()) != 0) {
00125 
00126     int eleTag = theEle->getTag();
00127     
00128     // check to see if all external nodes in node list
00129     bool in = true;
00130     const ID &theEleNodes = theEle->getExternalNodes();
00131     int numNodes = theEleNodes.Size();
00132 
00133     for (int i=0; i<numNodes; i++) {
00134       int nodeTag = theEleNodes(i);
00135       if (theNodes->getLocation(nodeTag) < 0) {
00136         in = false;
00137         i = numNodes;
00138       }
00139     }
00140     
00141     // if they are all in the node list add the ele to ele list
00142     if (in == true) 
00143       (*theElements)[loc++] = eleTag;
00144   }
00145 
00146   return 0;
00147 }
00148 
00149 
00150 int 
00151 MeshRegion::setElements(const ID &theEles)
00152 {
00153   // destroy the old lists
00154   if (theNodes != 0)
00155     delete theNodes;
00156   if (theElements != 0)
00157     delete theElements;
00158 
00159   // create new element & node lists
00160 
00161   int numEle = theEles.Size();
00162 
00163   theElements = new ID(0, numEle); // don't copy yet .. make sure ele in domain
00164   theNodes = new ID(0, numEle); // initial guess at size of ID
00165   if (theElements == 0 || theNodes == 0) {
00166     opserr << "MeshRegion::setElements() - ran out of memory\n";
00167     return -1;
00168   }
00169 
00170   // now loop over the elements in ele ID passed in to create the node & ele list
00171   // NOTE - only add those elements to the list that are in the domain
00172   // NOTE - node added to region if any element has it as an external node
00173   int locEle = 0;
00174   int locNode = 0;
00175 
00176 
00177   Domain *theDomain = this->getDomain();
00178   if (theDomain == 0) {
00179     opserr << "MeshRegion::setElements() - no domain yet set\n";
00180     return -1;
00181   }
00182 
00183   Element *theEle;
00184   for (int i=0; i<numEle; i++) {
00185     int eleTag = theEles(i);
00186     theEle = theDomain->getElement(eleTag);
00187     if (theEle != 0) {
00188 
00189       if (theElements->getLocation(eleTag) < 0)
00190           (*theElements)[locEle++] = eleTag;
00191 
00192       const ID &theEleNodes = theEle->getExternalNodes();
00193 
00194       for (int i=0; i<theEleNodes.Size(); i++) {
00195         int nodeTag = theEleNodes(i);
00196         // add the node tag if not already there
00197         if (theNodes->getLocation(nodeTag) < 0)
00198           (*theNodes)[locNode++] = nodeTag;
00199       }
00200     }
00201   }
00202 
00203   return 0;
00204 }
00205 
00206 
00207 const ID &
00208 MeshRegion::getNodes(void)
00209 {
00210   if (theNodes == 0)
00211     opserr << "FATAL::MeshRegion::getNodes(void) - no nodes yet set\n";
00212   
00213   return *theNodes;
00214 }
00215 
00216 const ID &
00217 MeshRegion::getElements(void)
00218 {
00219   if (theElements == 0)
00220     opserr << "FATAL::MeshRegion::getElements(void) - no elements yet set\n";
00221   
00222   return *theElements;
00223 }
00224 
00225 
00226 int
00227 MeshRegion::setRayleighDampingFactors(double alpham, double betak, double betak0, double betakc)
00228 {
00229   alphaM = alpham;
00230   betaK  = betak;
00231   betaK0 = betak0;
00232   betaKc = betakc;
00233 
00234   // now set the damping factors at the nodes & elements
00235   Domain *theDomain = this->getDomain();
00236   if (theDomain == 0) {
00237     opserr << "MeshRegion::setRayleighDampingFactors() - no domain yet set\n";
00238     return -1;
00239   }
00240   if (theElements != 0) {
00241     for (int i=0; i<theElements->Size(); i++) {
00242       int eleTag = (*theElements)(i);
00243       Element *theEle = theDomain->getElement(eleTag);
00244       if (theEle != 0)
00245         theEle->setRayleighDampingFactors(alphaM, betaK, betaK0, betaKc);
00246     }
00247   }
00248 
00249   if (theNodes != 0) {
00250     for (int i=0; i<theNodes->Size(); i++) {
00251       int nodTag = (*theNodes)(i);
00252       Node *theNode = theDomain->getNode(nodTag);
00253       if (theNode != 0)
00254         theNode->setRayleighDampingFactor(alphaM);
00255     }
00256   }
00257 
00258   return 0;
00259 }
00260 
00261 int 
00262 MeshRegion::sendSelf(int commitTag, Channel &theChannel)
00263 {
00264   // get my current database tag
00265   // NOTE - dbTag equals 0 if not sending to a database OR has not yet been sent
00266   int myDbTag = this->getDbTag();
00267 
00268   // into an ID we place all info needed to determine state of LoadPattern
00269   ID lpData(6);
00270   lpData(0) = currentGeoTag;
00271   lpData(1) = this->getTag();
00272 
00273   int numEle= theElements->Size();
00274   int numNod = theNodes->Size();
00275 
00276   lpData(2) = numEle;
00277   lpData(3) = numNod;
00278 
00279   if (dbNod == 0) {
00280     dbNod = theChannel.getDbTag();
00281     dbEle = theChannel.getDbTag();
00282   } 
00283 
00284   lpData(4) = dbNod;
00285   lpData(5) = dbEle;
00286 
00287   if (theChannel.sendID(myDbTag, commitTag, lpData) < 0) {
00288    opserr << "MeshRegion::sendSelf - channel failed to send the initial ID\n";
00289     return -1;
00290   }    
00291 
00292 
00293   // now check if data defining the objects in the LoadPAttern needs to be sent 
00294   // NOTE THIS APPROACH MAY NEED TO CHANGE FOR VERY LARGE PROBLEMS IF CHANNEL CANNOT
00295   // HANDLE VERY LARGE ID OBJECTS.
00296   if (lastGeoSendTag != currentGeoTag) {
00297     if (numNod != 0) 
00298       if (theChannel.sendID(dbNod, currentGeoTag, *theNodes) < 0) {
00299         opserr << "MeshRegion::sendSelf - channel failed to send the nodes\n";
00300         return -1;
00301       }
00302     if (numEle != 0) 
00303       if (theChannel.sendID(dbEle, currentGeoTag, *theElements) < 0) {
00304         opserr << "MeshRegion::sendSelf - channel failed to send the elements\n";
00305         return -1;
00306       }
00307 
00308     Vector dData(4);
00309     dData(0) = alphaM;
00310     dData(1) = betaK;
00311     dData(2) = betaK0;
00312     dData(3) = betaKc;
00313 
00314     if (theChannel.sendVector(dbEle, currentGeoTag, dData) < 0) {
00315      opserr << "MeshRegion::sendSelf - channel failed to send the elements\n";
00316       return -1;
00317     }  
00318 
00319     // set the lst send db tag so we don't have to send them again unless they change
00320     lastGeoSendTag = currentGeoTag;
00321   }    
00322 
00323 
00324   
00325   return 0;
00326 }
00327 
00328 int 
00329 MeshRegion::recvSelf(int commitTag, Channel &theChannel, 
00330                  FEM_ObjectBroker &theBroker)
00331 {
00332   // get my current database tag
00333   // NOTE - dbTag equals 0 if not sending to a database OR has not yet been sent
00334   int myDbTag = this->getDbTag();
00335 
00336   // into an ID we place all info needed to determine state of MeshRegion
00337   ID lpData(6);
00338 
00339   if (theChannel.recvID(myDbTag, commitTag, lpData) < 0) {
00340    opserr << "MeshRegion::recvSelf - channel failed to recv the initial ID\n";
00341     return -1;
00342   }
00343 
00344   // only recv the nodes & ele if not current
00345   if (currentGeoTag != lpData(0)) {
00346 
00347     currentGeoTag = lpData(0);
00348     this->setTag(lpData(1));
00349 
00350     int numEle = lpData(2);
00351     int numNod = lpData(3);
00352     if (theNodes != 0) {
00353       delete theNodes;
00354       theNodes = 0;
00355     }
00356     if (theElements != 0) {
00357       delete theElements;      
00358       theElements = 0;
00359     }
00360 
00361     if (numEle != 0)
00362       theElements = new ID(numEle); 
00363     if (numNod != 0)
00364       theNodes = new ID(numNod); 
00365 
00366     if (numNod != 0) 
00367       if (theChannel.recvID(dbNod, currentGeoTag, *theNodes) < 0) {
00368         opserr << "MeshRegion::sendSelf - channel failed to recv the nodes\n";
00369         return -1;
00370       }
00371     if (numEle != 0) 
00372       if (theChannel.recvID(dbEle, currentGeoTag, *theElements) < 0) {
00373         opserr << "MeshRegion::sendSelf - channel failed to recv the elements\n";
00374         return -1;
00375       }
00376 
00377     Vector dData(4);
00378 
00379     if (theChannel.sendVector(dbEle, currentGeoTag, dData) < 0) {
00380      opserr << "MeshRegion::sendSelf - channel failed to send the elements\n";
00381       return -1;
00382     }  
00383     alphaM = dData(0);
00384     betaK  = dData(1);
00385     betaK0 = dData(2);
00386     betaKc = dData(3);
00387   }
00388 
00389 
00390   this->setRayleighDampingFactors(alphaM, betaK, betaK0, betaKc);
00391   return 0;
00392 }
00393 
00394 
00395 void 
00396 MeshRegion::Print(OPS_Stream &s, int flag)
00397 {
00398   s << "Region: " << this->getTag() << endln;
00399   if (theElements != 0)
00400     s << "Elements: "<< *theElements;
00401   if (theNodes != 0)
00402     s << "Nodes: "<< *theNodes;
00403   if (alphaM != 0.0 || betaK != 0.0 || betaK0 != 0.0) {
00404     s << "rayleigh damping factors:: alphaM: " << alphaM << " betaK: ";
00405     s << betaK << " betaK0: " << betaK0 << endln;
00406   }
00407 }

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