EarthquakePattern.cppGo 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 ¶m) 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 //////////////////////////////////// |