Newmark.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.15 $
00022 // $Date: 2006/02/27 23:31:50 $
00023 // $Source: /usr/local/cvs/OpenSees/SRC/analysis/integrator/Newmark.cpp,v $
00024                                                                         
00025                                                                         
00026 // File: ~/analysis/integrator/Newmark.C
00027 // 
00028 // Written: fmk 
00029 // Created: 11/98
00030 // Revision: A
00031 //
00032 // Description: This file contains the implementation of the Newmark class.
00033 //
00034 // What: "@(#) Newmark.C, revA"
00035 
00036 #include <Newmark.h>
00037 #include <FE_Element.h>
00038 #include <LinearSOE.h>
00039 #include <AnalysisModel.h>
00040 #include <Vector.h>
00041 #include <DOF_Group.h>
00042 #include <DOF_GrpIter.h>
00043 #include <AnalysisModel.h>
00044 #include <Channel.h>
00045 #include <FEM_ObjectBroker.h>
00046 
00047 Newmark::Newmark()
00048 :TransientIntegrator(INTEGRATOR_TAGS_Newmark),
00049  displ(true), gamma(0), beta(0), 
00050  alphaM(0.0), betaK(0.0), betaKi(0.0), betaKc(0.0),
00051  c1(0.0), c2(0.0), c3(0.0), 
00052  Ut(0), Utdot(0), Utdotdot(0),  U(0), Udot(0), Udotdot(0),
00053  determiningMass(false)
00054 {
00055     
00056 }
00057 
00058 Newmark::Newmark(double theGamma, double theBeta, bool dispFlag)
00059 :TransientIntegrator(INTEGRATOR_TAGS_Newmark),
00060  displ(dispFlag),
00061  gamma(theGamma), beta(theBeta), 
00062  alphaM(0.0), betaK(0.0), betaKi(0.0), betaKc(0.0),
00063  c1(0.0), c2(0.0), c3(0.0), 
00064  Ut(0), Utdot(0), Utdotdot(0),  U(0), Udot(0), Udotdot(0),
00065  determiningMass(false)
00066 {
00067 
00068 }
00069 
00070 Newmark::Newmark(double theGamma, double theBeta, 
00071                  double alpham, double betak, 
00072                  double betaki, double betakc,
00073                  bool dispFlag)
00074 :TransientIntegrator(INTEGRATOR_TAGS_Newmark),
00075  displ(dispFlag),
00076  gamma(theGamma), beta(theBeta), 
00077  alphaM(alpham), betaK(betak), betaKi(betaki), betaKc(betakc),
00078  c1(0.0), c2(0.0), c3(0.0), 
00079  Ut(0), Utdot(0), Utdotdot(0),  U(0), Udot(0), Udotdot(0),
00080  determiningMass(false) 
00081 {
00082 
00083 }
00084 
00085 Newmark::~Newmark()
00086 {
00087   // clean up the memory created
00088   if (Ut != 0)
00089     delete Ut;
00090   if (Utdot != 0)
00091     delete Utdot;
00092   if (Utdotdot != 0)
00093     delete Utdotdot;
00094   if (U != 0)
00095     delete U;
00096   if (Udot != 0)
00097     delete Udot;
00098   if (Udotdot != 0)
00099     delete Udotdot;
00100 }
00101 
00102 
00103 
00104 
00105 
00106 int
00107 Newmark::newStep(double deltaT)
00108 {
00109   if (beta == 0 || gamma == 0 ) {
00110     opserr << "Newton::newStep() - error in variable\n";
00111     opserr << "gamma = " << gamma << " beta= " << beta << endln;
00112     return -1;
00113   }
00114 
00115 
00116   // get a pointer to the AnalysisModel
00117   AnalysisModel *theModel = this->getAnalysisModelPtr();
00118 
00119   if (displ == true) {
00120     if (deltaT <= 0.0) {
00121       opserr << "Newton::newStep() - error in variable\n";
00122       opserr << "dT = " << deltaT << endln;
00123       return -2;        
00124     }
00125     c1 = 1.0;
00126     c2 = gamma/(beta*deltaT);
00127     c3 = 1.0/(beta*deltaT*deltaT);
00128   } else {
00129     c1 = beta*deltaT*deltaT;
00130     c2 = gamma*deltaT;
00131     c3 = 1.0;
00132   }
00133     
00134   if (U == 0) {
00135     opserr << "Newton::newStep() - domainChange() failed or hasn't been called\n";
00136     return -3;  
00137   }
00138 
00139   // set response at t to be that at t+delta t of previous step
00140   (*Ut) = *U;        
00141   (*Utdot) = *Udot;  
00142   (*Utdotdot) = *Udotdot;  
00143 
00144   if (displ == true) {
00145 
00146     // set new velocity and accelerations at t + delta t
00147     double a1 = (1.0 - gamma/beta); 
00148     double a2 = (deltaT)*(1.0 - 0.5*gamma/beta);
00149     // (*Udot) *= a1;
00150     Udot->addVector(a1, *Utdotdot,a2);
00151 
00152     double a3 = -1.0/(beta*deltaT);
00153     double a4 = 1 - 0.5/beta;
00154     // (*Udotdot) *= a4;  
00155     Udotdot->addVector(a4, *Utdot,a3);
00156     
00157   } else {
00158     // set new displacement and velocity at t + delta t      
00159     double a1 = (deltaT*deltaT/2.0); 
00160     U->addVector(1.0, *Utdot,deltaT);
00161     U->addVector(1.0, *Utdotdot,a1);
00162     
00163     Udot->addVector(1.0, *Utdotdot,deltaT);
00164   }
00165 
00166   // set the new trial response quantities
00167   theModel->setResponse(*U,*Udot,*Udotdot);        
00168 
00169   // increment the time and apply the load
00170   double time = theModel->getCurrentDomainTime();
00171   time +=deltaT;
00172   if (theModel->updateDomain(time, deltaT) < 0) {
00173     opserr << "Newmark::newStep() - failed to update the domain\n";
00174     return -4;
00175   }
00176   
00177   return 0;
00178 }
00179 
00180 
00181 
00182 int
00183 Newmark::revertToLastStep()
00184 {
00185   // set response at t+delta t to be that at t .. for next newStep
00186   if (U != 0) {
00187     (*U) = *Ut;        
00188     (*Udot) = *Utdot;  
00189     (*Udotdot) = *Utdotdot;  
00190   }
00191   return 0;
00192 }
00193 
00194 
00195 int
00196 Newmark::formEleTangent(FE_Element *theEle)
00197 {
00198   if (determiningMass == true)
00199     return 0;
00200 
00201   theEle->zeroTangent();
00202 
00203   if (statusFlag == CURRENT_TANGENT) {
00204     theEle->addKtToTang(c1);
00205     theEle->addCtoTang(c2);
00206     theEle->addMtoTang(c3);
00207   } else if (statusFlag == INITIAL_TANGENT) {
00208     theEle->addKiToTang(c1);
00209     theEle->addCtoTang(c2);
00210     theEle->addMtoTang(c3);
00211   }
00212 
00213   return 0;
00214 }    
00215 
00216 
00217 int
00218 Newmark::formNodTangent(DOF_Group *theDof)
00219 {
00220   if (determiningMass == true)
00221     return 0;
00222 
00223   theDof->zeroTangent();
00224   theDof->addMtoTang(c3);
00225   theDof->addCtoTang(c2);      
00226 
00227   return(0);
00228 }    
00229 
00230 
00231 
00232 int 
00233 Newmark::domainChanged()
00234 {
00235   AnalysisModel *myModel = this->getAnalysisModelPtr();
00236   LinearSOE *theLinSOE = this->getLinearSOEPtr();
00237   const Vector &x = theLinSOE->getX();
00238   int size = x.Size();
00239 
00240   // if damping factors exist set them in the ele & node of the domain
00241   if (alphaM != 0.0 || betaK != 0.0 || betaKi != 0.0 || betaKc != 0.0)
00242     myModel->setRayleighDampingFactors(alphaM, betaK, betaKi, betaKc);
00243   
00244   // create the new Vector objects
00245   if (Ut == 0 || Ut->Size() != size) {
00246 
00247     // delete the old
00248     if (Ut != 0)
00249       delete Ut;
00250     if (Utdot != 0)
00251       delete Utdot;
00252     if (Utdotdot != 0)
00253       delete Utdotdot;
00254     if (U != 0)
00255       delete U;
00256     if (Udot != 0)
00257       delete Udot;
00258     if (Udotdot != 0)
00259       delete Udotdot;
00260     
00261     // create the new
00262     Ut = new Vector(size);
00263     Utdot = new Vector(size);
00264     Utdotdot = new Vector(size);
00265     U = new Vector(size);
00266     Udot = new Vector(size);
00267     Udotdot = new Vector(size);
00268 
00269     // cheack we obtained the new
00270     if (Ut == 0 || Ut->Size() != size ||
00271         Utdot == 0 || Utdot->Size() != size ||
00272         Utdotdot == 0 || Utdotdot->Size() != size ||
00273         U == 0 || U->Size() != size ||
00274         Udot == 0 || Udot->Size() != size ||
00275         Udotdot == 0 || Udotdot->Size() != size) {
00276       
00277       opserr << "Newmark::domainChanged - ran out of memory\n";
00278 
00279       // delete the old
00280       if (Ut != 0)
00281         delete Ut;
00282       if (Utdot != 0)
00283         delete Utdot;
00284       if (Utdotdot != 0)
00285         delete Utdotdot;
00286       if (U != 0)
00287         delete U;
00288       if (Udot != 0)
00289         delete Udot;
00290       if (Udotdot != 0)
00291         delete Udotdot;
00292 
00293       Ut = 0; Utdot = 0; Utdotdot = 0;
00294       U = 0; Udot = 0; Udotdot = 0;
00295       return -1;
00296     }
00297   }        
00298     
00299   // now go through and populate U, Udot and Udotdot by iterating through
00300   // the DOF_Groups and getting the last committed velocity and accel
00301 
00302   DOF_GrpIter &theDOFs = myModel->getDOFs();
00303   DOF_Group *dofPtr;
00304     
00305   while ((dofPtr = theDOFs()) != 0) {
00306     const ID &id = dofPtr->getID();
00307     int idSize = id.Size();
00308 
00309 
00310         int i;
00311     const Vector &disp = dofPtr->getCommittedDisp();    
00312     for (i=0; i < idSize; i++) {
00313       int loc = id(i);
00314       if (loc >= 0) {
00315         (*U)(loc) = disp(i);            
00316       }
00317     }
00318 
00319     const Vector &vel = dofPtr->getCommittedVel();
00320     for (i=0; i < idSize; i++) {
00321       int loc = id(i);
00322       if (loc >= 0) {
00323         (*Udot)(loc) = vel(i);
00324       }
00325     }
00326 
00327     const Vector &accel = dofPtr->getCommittedAccel();  
00328     for (i=0; i < idSize; i++) {
00329       int loc = id(i);
00330       if (loc >= 0) {
00331         (*Udotdot)(loc) = accel(i);
00332       }
00333     }
00344   }    
00345   
00346   return 0;
00347 }
00348 
00349 
00350 int
00351 Newmark::update(const Vector &deltaU)
00352 {
00353   AnalysisModel *theModel = this->getAnalysisModelPtr();
00354   if (theModel == 0) {
00355     opserr << "WARNING Newmark::update() - no AnalysisModel set\n";
00356     return -1;
00357   }     
00358 
00359   // check domainChanged() has been called, i.e. Ut will not be zero
00360   if (Ut == 0) {
00361     opserr << "WARNING Newmark::update() - domainChange() failed or not called\n";
00362     return -2;
00363 }       
00364 
00365   // check deltaU is of correct size
00366   if (deltaU.Size() != U->Size()) {
00367     opserr << "WARNING Newmark::update() - Vectors of incompatable size ";
00368     opserr << " expecting " << U->Size() << " obtained " << deltaU.Size() << endln;
00369     return -3;
00370   }
00371     
00372   //  determine the response at t+delta t
00373   if (displ == true) {
00374     (*U) += deltaU;
00375     Udot->addVector(1.0, deltaU,c2);
00376     Udotdot->addVector(1.0, deltaU,c3);
00377   } else {
00378     (*Udotdot) += deltaU;
00379     U->addVector(1.0, deltaU,c1);
00380     Udot->addVector(1.0, deltaU,c2);
00381   }
00382 
00383   // update the responses at the DOFs
00384   theModel->setResponse(*U,*Udot,*Udotdot);        
00385   if (theModel->updateDomain() < 0) {
00386     opserr << "Newmark::update() - failed to update the domain\n";
00387     return -4;
00388   }
00389 
00390   return 0;
00391 }    
00392 
00393 int
00394 Newmark::sendSelf(int cTag, Channel &theChannel)
00395 {
00396     Vector data(8);
00397     data(0) = gamma;
00398     data(1) = beta;
00399     if (displ == true) 
00400       data(2) = 1.0;
00401     else
00402       data(2) = 0.0;
00403 
00404     data(3) = 1.0;      
00405     data(4) = alphaM;
00406     data(5) = betaK;
00407     data(6) = betaKi;
00408     data(7) = betaKc;
00409     
00410     if (theChannel.sendVector(this->getDbTag(), cTag, data) < 0) {
00411         opserr << "WARNING Newmark::sendSelf() - could not send data\n";
00412         return -1;
00413     }   
00414     return 0;
00415 }
00416 
00417 int
00418 Newmark::recvSelf(int cTag, Channel &theChannel, FEM_ObjectBroker &theBroker)
00419 {
00420     Vector data(8);
00421     if (theChannel.recvVector(this->getDbTag(), cTag, data) < 0) {
00422         opserr << "WARNING Newmark::recvSelf() - could not receive data\n";
00423         gamma = 0.5; beta = 0.25; 
00424         return -1;
00425     }
00426     
00427     gamma = data(0);
00428     beta = data(1);
00429     if (data(2) == 1.0)
00430       displ = true;
00431     else
00432       displ = false;
00433     alphaM = data(4);
00434     betaK = data(5);
00435     betaKi = data(6);
00436     betaKc = data(7);
00437       
00438     return 0;
00439     
00440 }
00441 
00442 void
00443 Newmark::Print(OPS_Stream &s, int flag)
00444 {
00445     AnalysisModel *theModel = this->getAnalysisModelPtr();
00446     if (theModel != 0) {
00447         double currentTime = theModel->getCurrentDomainTime();
00448         s << "\t Newmark - currentTime: " << currentTime;
00449         s << "  gamma: " << gamma << "  beta: " << beta << endln;
00450         s << " c1: " << c1 << " c2: " << c2 << " c3: " << c3 << endln;
00451         s << "  Rayleigh Damping - alphaM: " << alphaM;
00452         s << "  betaK: " << betaK << "   betaKi: " << betaKi << endln;      
00453     } else 
00454         s << "\t Newmark - no associated AnalysisModel\n";
00455 }
00456 
00457 // AddingSensitivity:BEGIN //////////////////////////////
00458 int
00459 Newmark::revertToStart()
00460 {
00461   if (Ut != 0) 
00462     Ut->Zero();
00463   if (Utdot != 0) 
00464     Utdot->Zero();
00465   if (Utdotdot != 0) 
00466     Utdotdot->Zero();
00467   if (U != 0) 
00468     U->Zero();
00469   if (Udot != 0) 
00470     Udot->Zero();
00471   if (Udotdot != 0) 
00472     Udotdot->Zero();
00473   
00474   return 0;
00475 }
00476 // AddingSensitivity:END ////////////////////////////////
00477 

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