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

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