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

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