EarthquakePattern.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.9 $
00022 // $Date: 2006/09/05 20:51:38 $
00023 // $Source: /usr/local/cvs/OpenSees/SRC/domain/pattern/EarthquakePattern.cpp,v $
00024                                                                         
00025 // Written: fmk 11/98
00026 // Revised:
00027 //
00028 // Purpose: This file contains the class definition for EarthquakePattern.
00029 // EarthquakePattern is an abstract class.
00030 
00031 #include <EarthquakePattern.h>
00032 #include <GroundMotion.h>
00033 
00034 #include <Domain.h>
00035 #include <NodeIter.h>
00036 #include <Node.h>
00037 #include <ElementIter.h>
00038 #include <Element.h>
00039 #include <stdlib.h>
00040 #include <Channel.h>
00041 #include <ErrorHandler.h>
00042 
00043 EarthquakePattern::EarthquakePattern(int tag, int _classTag)
00044   :LoadPattern(tag, _classTag), theMotions(0), numMotions(0), uDotG(0), uDotDotG(0), currentTime(0.0), parameterID(0)
00045 {
00046 
00047 }
00048 
00049 
00050 EarthquakePattern::~EarthquakePattern()
00051 {
00052   // invoke the destructor on all ground motions supplied
00053   for (int i=0; i<numMotions; i++)
00054       delete theMotions[i];
00055   
00056   if (theMotions != 0)
00057     //    free ((void *)theMotions);
00058     delete [] theMotions;
00059 
00060   if (uDotG != 0)
00061     delete uDotG;
00062 
00063   if (uDotDotG != 0)
00064     delete uDotDotG;
00065 }
00066 
00067 
00068 
00069 void 
00070 EarthquakePattern::applyLoad(double time)
00071 {
00072   // see if quick return, i.e. no Ground Motions or domain set
00073   if (numMotions == 0)
00074     return;
00075 
00076   // check if setLoadConstant() has been called
00077   if (isConstant != 0)
00078     currentTime = time;
00079 
00080   Domain *theDomain = this->getDomain();
00081   if (theDomain == 0)
00082     return;
00083 
00084 
00085   // set the vel and accel vector
00086   for (int i=0; i<numMotions; i++) {
00087     //    (*uDotG)(i) = theMotions[i]->getVel(currentTime);
00088     (*uDotDotG)(i) = theMotions[i]->getAccel(currentTime);
00089   }
00090 
00091   NodeIter &theNodes = theDomain->getNodes();
00092   Node *theNode;
00093   while ((theNode = theNodes()) != 0) 
00094     theNode->addInertiaLoadToUnbalance(*uDotDotG, 1.0);
00095   
00096 
00097   ElementIter &theElements = theDomain->getElements();
00098   Element *theElement;
00099   while ((theElement = theElements()) != 0) 
00100     theElement->addInertiaLoadToUnbalance(*uDotDotG);
00101 }
00102     
00103 void 
00104 EarthquakePattern::applyLoadSensitivity(double time)
00105 {
00106   // see if quick return, i.e. no Ground Motions or domain set
00107   if (numMotions == 0)
00108     return;
00109 
00110   Domain *theDomain = this->getDomain();
00111   if (theDomain == 0)
00112     return;
00113 
00114 
00115   // set the vel and accel vector
00116   for (int i=0; i<numMotions; i++) {
00117     (*uDotG)(i) = theMotions[i]->getVel(time);
00118     if (parameterID != 0) { // Something is random in the motions
00119       (*uDotDotG)(i) = theMotions[i]->getAccelSensitivity(time);
00120     }
00121     else {
00122       (*uDotDotG)(i) = theMotions[i]->getAccel(time);
00123     }
00124   }
00125 
00126   bool somethingRandomInMotions = false;
00127   if (parameterID != 0) {
00128     somethingRandomInMotions = true;
00129   }
00130 
00131 
00132   NodeIter &theNodes = theDomain->getNodes();
00133   Node *theNode;
00134   while ((theNode = theNodes()) != 0) 
00135         theNode->addInertiaLoadSensitivityToUnbalance(*uDotDotG, 1.0,  somethingRandomInMotions);
00136 
00137 
00138   ElementIter &theElements = theDomain->getElements();
00139   Element *theElement;
00140   while ((theElement = theElements()) != 0) 
00141         theElement->addInertiaLoadSensitivityToUnbalance(*uDotDotG,  somethingRandomInMotions);
00142 }
00143     
00144 int
00145 EarthquakePattern::addMotion(GroundMotion &theMotion)
00146 {
00147   // make space for new
00148   GroundMotion **newMotions = new GroundMotion *[numMotions+1];
00149   //  GroundMotion **newMotions = (GroundMotion **)malloc(sizeof(GroundMotion *)*(numMotions+1));
00150   if (newMotions == 0) {
00151     opserr << "EarthquakePattern::addMotion - could not add new, out of mem\n";
00152     return -1;
00153   }
00154   
00155   // copy old
00156   for (int i=0; i<numMotions; i++)
00157     newMotions[i] = theMotions[i];
00158 
00159   // add the new motion to new
00160   newMotions[numMotions] = &theMotion;
00161 
00162   // delete the old
00163   if (theMotions != 0)
00164     delete [] theMotions;
00165 
00166   // reset
00167   theMotions = newMotions;
00168   numMotions++;
00169 
00170   // delete old vectors and create new ones
00171   if (uDotG != 0)
00172     delete uDotG;
00173   uDotG = new Vector(numMotions);
00174 
00175   if (uDotDotG != 0)
00176     delete uDotDotG;
00177   uDotDotG = new Vector(numMotions);
00178 
00179   if (uDotDotG == 0 || uDotDotG->Size() == 0 || uDotG == 0 || uDotG->Size() == 0) {
00180     opserr << "EarthquakePattern::addMotion - ran out of memory creating vectors\n";
00181     numMotions = 0;
00182     return -2;
00183   }
00184   return 0;
00185 }
00186 
00187 
00188 bool
00189 EarthquakePattern::addSP_Constraint(SP_Constraint *)
00190 {
00191   opserr << "EarthquakePattern::addSP_Constraint() - cannot add SP_Constraint to EQ pattern\n";
00192   return false;
00193 }
00194 
00195 bool
00196 EarthquakePattern::addNodalLoad(NodalLoad *)
00197 {
00198   opserr << "EarthquakePattern::addNodalLoad() - cannot add NodalLoad to EQ pattern\n";  
00199   return false;
00200 }
00201 
00202 bool
00203 EarthquakePattern::addElementalLoad(ElementalLoad *)
00204 {
00205   opserr << "EarthquakePattern::addElementalLoad() - cannot add ElementalLoad to EQ pattern\n";    
00206   return false;
00207 }
00208 
00209 
00210 /* **********************************************************************************************
00211 int 
00212 EarthquakePattern::sendSelf(int commitTag, Channel &theChannel)
00213 {
00214   // first send the tag and info about the number of ground motions
00215   int myDbTag = this->getDbTag();
00216   ID theData(2);
00217   theData(0) = this->getTag();
00218   theData(1) = numMotions;
00219 
00220   if (theChannel.sendID(myDbTag, commitTag, theData) < 0) {
00221     g3ErrorHandler->warning("EarthquakePattern::sendSelf - channel failed to send the initial ID");
00222     return -1;
00223   }    
00224 
00225   // now for each motion we send it's classsss tag and dbtag
00226   ID theMotionsData(2*numMotions);
00227   for (int i=0; i<numMotions; i++) {
00228     theMotionsData[i] = theMotions[i]->getClassTag();
00229     int motionsDbTag = theMotions[i]->getDbTag();
00230     if (motionsDbTag == 0) {
00231       motionsDbTag = theChannel.getDbTag();
00232       theMotions[i]->setDbTag(motionsDbTag);
00233     }
00234     theMotionsData[i+numMotions] = motionsDbTag;
00235   }
00236 
00237   if (theChannel.sendID(myDbTag, commitTag, theMotionsData) < 0) {
00238     g3ErrorHandler->warning("EarthquakePattern::sendSelf - channel failed to send the motions ID");
00239     return -1;
00240   }    
00241 
00242   // now we send each motion
00243   for (int j=0; j<numMotions; j++)
00244     if (theMotions[j]->sendSelf(commitTag, theChannel) < 0) {
00245       g3ErrorHandler->warning("EarthquakePattern::sendSelf - motion no: %d failed in sendSelf", j);
00246       return -1;
00247     }
00248 
00249   // if get here successfull
00250   return 0;
00251 }
00252 
00253 int 
00254 EarthquakePattern::recvSelf(int commitTag, Channel &theChannel, 
00255                          FEM_ObjectBroker &theBroker)
00256 {
00257   // first get the tag and info about the number of ground motions from the Channel
00258   int myDbTag = this->getDbTag();
00259   ID theData(2);
00260   if (theChannel.recvID(myDbTag, commitTag, theData) < 0) {
00261     g3ErrorHandler->warning("EarthquakePattern::recvSelf - channel failed to recv the initial ID");
00262     return -1;
00263   }    
00264   
00265   // set current tag
00266   this->setTag(theData(0));
00267 
00268   // now get info about each channel
00269   ID theMotionsData (2*theData(1));
00270   if (theChannel.recvID(myDbTag, commitTag, theMotionsData) < 0) {
00271     g3ErrorHandler->warning("EarthquakePattern::recvSelf - channel failed to recv the motions ID");
00272     return -1;
00273   }    
00274 
00275 
00276   if (numMotions != theData(1)) {
00277 
00278     //
00279     // we must delete the old motions and create new ones and then invoke recvSelf on these new ones
00280     //
00281 
00282     if (numMotions != 0) {
00283       for (int i=0; i<numMotions; i++)
00284         delete theMotions[i];
00285       delete [] theMotions;
00286     }
00287     numMotions = theData[1];
00288     theMotions = new (GroundMotion *)[numMotions];
00289     if (theMotions == 0) {
00290       g3ErrorHandler->warning("EarthquakePattern::recvSelf - out of memory creating motion array of size %d\n", numMotions);
00291       numMotions = 0;
00292       return -1;
00293     }    
00294 
00295     for (int i=0; i<numMotions; i++) {
00296       theMotions[i] = theBroker.getNewGroundMotion(theMotionsData[i]);
00297       if (theMotions[i] == 0) {
00298         g3ErrorHandler->warning("EarthquakePattern::recvSelf - out of memory creating motion array of size %d\n", numMotions);
00299         numMotions = 0;
00300         return -1;
00301       }    
00302       theMotions[i]->setDbTag(theMotionsData[i+numMotions]);
00303       if (theMotions[i]->recvSelf(commitTag, theChannel, theBroker) < 0) {
00304         g3ErrorHandler->warning("EarthquakePattern::recvSelf - motion no: %d failed in recvSelf", i);
00305         numMotions = 0;
00306         return -1;
00307       }      
00308     }
00309 
00310   } else {
00311 
00312     // 
00313     // we invoke rrecvSelf on the motions, note if a motion not of correct class
00314     // we must invoke the destructor on the motion and create a new one of correct type
00315     //
00316 
00317     for (int i=0; i<numMotions; i++) {
00318       if (theMotions[i]->getClassTag() == theMotionsData[i]) {
00319         if (theMotions[i]->recvSelf(commitTag, theChannel, theBroker) < 0) {
00320           g3ErrorHandler->warning("EarthquakePattern::recvSelf - motion no: %d failed in recvSelf", i);
00321           return -1;
00322         }      
00323       } else {
00324         // motion not of correct type
00325         delete theMotions[i];
00326         theMotions[i] = theBroker.getNewGroundMotion(theMotionsData[i]);
00327         if (theMotions[i] == 0) {
00328           g3ErrorHandler->warning("EarthquakePattern::recvSelf - out of memory creating motion array of size %d\n", numMotions);
00329           numMotions = 0;
00330           return -1;
00331         }    
00332         theMotions[i]->setDbTag(theMotionsData[i+numMotions]);
00333         if (theMotions[i]->recvSelf(commitTag, theChannel, theBroker) < 0) {
00334           g3ErrorHandler->warning("EarthquakePattern::recvSelf - motion no: %d failed in recvSelf", i);
00335           numMotions = 0;
00336           return -1;
00337         }      
00338       }
00339     }    
00340   }
00341 
00342   // if get here successfull
00343   return 0;
00344 }
00345 
00346 
00347 ***************************************************************************************** */
00348 
00349 void 
00350 EarthquakePattern::Print(OPS_Stream &s, int flag)
00351 {
00352   opserr << "EarthquakePattern::Print() - not yet implemented\n";    
00353 }
00354 
00355 /* ****************************************************************************************
00356 // method to obtain a blank copy of the LoadPattern
00357 LoadPattern *
00358 EarthquakePattern::getCopy(void)
00359 {
00360   EarthquakePattern *theCopy = new EarthquakePattern(0, 0);
00361   theCopy->setTag(this->getTag);
00362   theCopy->numMotions = numMotions;
00363   theCopy->theMotions = new (GroundMotion *)[numMotions];
00364   for (int i=0; i<numMotions; i++)
00365     theCopy->theMotions[i] = theMotions[i];
00366 
00367   return 0;
00368 }
00369 ***************************************************************************************** */
00370 
00371 
00372 // AddingSensitivity:BEGIN ////////////////////////////////////
00373 int
00374 EarthquakePattern::setParameter(const char **argv, int argc, Parameter &param)
00375 {
00376   if (argc < 2)
00377     return -1;
00378 
00379   // This is not general, yet
00380 
00381   if (strstr(argv[0],"randomProcessDiscretizer") != 0) {
00382     return theMotions[0]->setParameter(&argv[1], argc-1, param);
00383   }
00384   else
00385     return 0;
00386 
00387 }
00388 
00389 int
00390 EarthquakePattern::updateParameter(int pparameterID, Information &info)
00391 {
00392   return theMotions[0]->updateParameter(pparameterID, info);
00393 }
00394 
00395 int
00396 EarthquakePattern::activateParameter(int pparameterID)
00397 {
00398   parameterID = pparameterID;
00399 
00400   return theMotions[0]->activateParameter(pparameterID);
00401 }
00402 // AddingSensitivity:END ////////////////////////////////////

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