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

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