AlphaOS.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.2 $
00022 // $Date: 2005/12/21 00:31:57 $
00023 // $Source: /usr/local/cvs/OpenSees/SRC/analysis/integrator/AlphaOS.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 AlphaOS class.
00030 //
00031 // What: "@(#)E AlphaOS.cpp, revA"
00032 
00033 #include <AlphaOS.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 <FE_EleIter.h>
00044 
00045 AlphaOS::AlphaOS()
00046     : TransientIntegrator(INTEGRATOR_TAGS_AlphaOS),
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), Upt(0), Uptdot(0)
00052 {
00053     
00054 }
00055 
00056 
00057 AlphaOS::AlphaOS(double _alpha)
00058     : TransientIntegrator(INTEGRATOR_TAGS_AlphaOS),
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), Upt(0), Uptdot(0)
00064 {
00065     
00066 }
00067 
00068 
00069 AlphaOS::AlphaOS(double _alpha, 
00070     double _alphaM, double _betaK, double _betaKi, double _betaKc)
00071     : TransientIntegrator(INTEGRATOR_TAGS_AlphaOS),
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), Upt(0), Uptdot(0)
00077 {
00078     
00079 }
00080 
00081 
00082 AlphaOS::AlphaOS(double _alpha, double _beta, double _gamma)
00083     : TransientIntegrator(INTEGRATOR_TAGS_AlphaOS),
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), Upt(0), Uptdot(0)
00089 {
00090     
00091 }
00092 
00093 
00094 AlphaOS::AlphaOS(double _alpha, double _beta, double _gamma,
00095     double _alphaM, double _betaK, double _betaKi, double _betaKc)
00096     : TransientIntegrator(INTEGRATOR_TAGS_AlphaOS),
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), Upt(0), Uptdot(0)
00102 {
00103     
00104 }
00105 
00106 
00107 AlphaOS::~AlphaOS()
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     if (Upt != 0)
00127         delete Upt;
00128     if (Uptdot != 0)
00129         delete Uptdot;
00130 }
00131 
00132 
00133 int AlphaOS::newStep(double _deltaT)
00134 {
00135     updateCount = 0;
00136 
00137     deltaT = _deltaT;
00138     if (beta == 0 || gamma == 0 )  {
00139         opserr << "AlphaOS::newStep() - error in variable\n";
00140         opserr << "gamma = " << gamma << " beta = " << beta << endln;
00141         return -1;
00142     }
00143     
00144     if (deltaT <= 0.0)  {
00145         opserr << "AlphaOS::newStep() - error in variable\n";
00146         opserr << "dT = " << deltaT << "\n";
00147         return -2;      
00148     }
00149     
00150     // get a pointer to the AnalysisModel
00151     AnalysisModel *theModel = this->getAnalysisModelPtr();
00152     
00153     // set the constants
00154     c1 = 1.0;
00155     c2 = gamma/(beta*deltaT);
00156     c3 = 1.0/(beta*deltaT*deltaT);
00157     
00158     if (U == 0)  {
00159         opserr << "AlphaOS::newStep() - domainChange() failed or hasn't been called\n";
00160         return -3;      
00161     }
00162     
00163     // set response at t to be that at t+deltaT of previous step
00164     (*Ut) = *U;  
00165     (*Utdot) = *Udot;  
00166     (*Utdotdot) = *Udotdot;  
00167     
00168     // determine new displacements and velocities at time t+deltaT
00169     U->addVector(1.0, *Utdot, deltaT);
00170     double a1 = (0.5 - beta)*deltaT*deltaT;
00171     U->addVector(1.0, *Utdotdot, a1);
00172     
00173     double a2 = deltaT*(1.0 - gamma);
00174     Udot->addVector(1.0, *Utdotdot, a2);
00175             
00176     // determine the displacements and velocities at t+alpha*deltaT
00177     (*Ualpha) = *Upt;
00178     Ualpha->addVector((1.0-alpha), *U, alpha);
00179     
00180     (*Ualphadot) = *Uptdot;
00181     Ualphadot->addVector((1.0-alpha), *Udot, alpha);
00182         
00183     // set the trial response quantities for the elements
00184     theModel->setDisp(*Ualpha);
00185     theModel->setVel(*Ualphadot);
00186     
00187     // increment the time to t+alpha*deltaT and apply the load
00188     double time = theModel->getCurrentDomainTime();
00189     time += alpha*deltaT;
00190     if (theModel->updateDomain(time, deltaT) < 0)  {
00191         opserr << "AlphaOS::newStep() - failed to update the domain\n";
00192         return -4;
00193     }
00194 
00195     // determine the velocities and accelerations at t+alpha*deltaT
00196     (*Ualphadot) = *Utdot;
00197     Ualphadot->addVector((1.0-alpha), *Udot, alpha);
00198 
00199     Udotdot->Zero();
00200 
00201     // set the trial response quantities for the nodes
00202     theModel->setVel(*Ualphadot);
00203     theModel->setAccel(*Udotdot);
00204     
00205     return 0;
00206 }
00207 
00208 
00209 int AlphaOS::revertToLastStep()
00210 {
00211     // set response at t+deltaT to be that at t .. for next step
00212     if (U != 0)  {
00213         (*U) = *Ut;
00214         (*Udot) = *Utdot;
00215         (*Udotdot) = *Utdotdot;
00216     }
00217 
00218     return 0;
00219 }
00220 
00221 
00222 int AlphaOS::formEleTangent(FE_Element *theEle)
00223 {
00224     theEle->zeroTangent();
00225     
00226     theEle->addKiToTang(alpha*c1);
00227     theEle->addCtoTang(alpha*c2);
00228     theEle->addMtoTang(c3);
00229     
00230     return 0;
00231 }    
00232 
00233 
00234 int AlphaOS::formNodTangent(DOF_Group *theDof)
00235 {
00236     theDof->zeroTangent();
00237     
00238     theDof->addCtoTang(alpha*c2);
00239     theDof->addMtoTang(c3);
00240     
00241     return 0;
00242 }    
00243 
00244 
00245 int AlphaOS::domainChanged()
00246 {
00247     AnalysisModel *myModel = this->getAnalysisModelPtr();
00248     LinearSOE *theLinSOE = this->getLinearSOEPtr();
00249     const Vector &x = theLinSOE->getX();
00250     int size = x.Size();
00251     
00252     // if damping factors exist set them in the element & node of the domain
00253     if (alphaM != 0.0 || betaK != 0.0 || betaKi != 0.0 || betaKc != 0.0)
00254         myModel->setRayleighDampingFactors(alphaM, betaK, betaKi, betaKc);
00255     
00256     // create the new Vector objects
00257     if (Ut == 0 || Ut->Size() != size)  {
00258         
00259         // delete the old
00260         if (Ut != 0)
00261             delete Ut;
00262         if (Utdot != 0)
00263             delete Utdot;
00264         if (Utdotdot != 0)
00265             delete Utdotdot;
00266         if (U != 0)
00267             delete U;
00268         if (Udot != 0)
00269             delete Udot;
00270         if (Udotdot != 0)
00271             delete Udotdot;
00272         if (Ualpha != 0)
00273             delete Ualpha;
00274         if (Ualphadot != 0)
00275             delete Ualphadot;
00276         if (Upt != 0)
00277             delete Upt;
00278         if (Uptdot != 0)
00279             delete Uptdot;
00280         
00281         // create the new
00282         Ut = new Vector(size);
00283         Utdot = new Vector(size);
00284         Utdotdot = new Vector(size);
00285         U = new Vector(size);
00286         Udot = new Vector(size);
00287         Udotdot = new Vector(size);
00288         Ualpha = new Vector(size);
00289         Ualphadot = new Vector(size);
00290         Upt = new Vector(size);
00291         Uptdot = new Vector(size);
00292         
00293         // check we obtained the new
00294         if (Ut == 0 || Ut->Size() != size ||
00295             Utdot == 0 || Utdot->Size() != size ||
00296             Utdotdot == 0 || Utdotdot->Size() != size ||
00297             U == 0 || U->Size() != size ||
00298             Udot == 0 || Udot->Size() != size ||
00299             Udotdot == 0 || Udotdot->Size() != size ||
00300             Ualpha == 0 || Ualpha->Size() != size ||
00301             Ualphadot == 0 || Ualphadot->Size() != size ||
00302             Upt == 0 || Upt->Size() != size ||
00303             Uptdot == 0 || Uptdot->Size() != size)  {
00304             
00305             opserr << "AlphaOS::domainChanged - ran out of memory\n";
00306             
00307             // delete the old
00308             if (Ut != 0)
00309                 delete Ut;
00310             if (Utdot != 0)
00311                 delete Utdot; 
00312             if (Utdotdot != 0)
00313                 delete Utdotdot;
00314             if (U != 0)
00315                 delete U;
00316             if (Udot != 0)
00317                 delete Udot;
00318             if (Udotdot != 0)
00319                 delete Udotdot;
00320             if (Ualpha != 0)
00321                 delete Ualpha;
00322             if (Ualphadot != 0)
00323                 delete Ualphadot;
00324             if (Upt != 0)
00325                 delete Upt;
00326             if (Uptdot != 0)
00327                 delete Uptdot;
00328             
00329             Ut = 0; Utdot = 0; Utdotdot = 0;
00330             U = 0; Udot = 0; Udotdot = 0;
00331             Ualpha = 0; Ualphadot = 0;
00332             Upt = 0; Uptdot = 0;
00333 
00334             return -1;
00335         }
00336     }        
00337     
00338     // now go through and populate U, Udot and Udotdot by iterating through
00339     // the DOF_Groups and getting the last committed velocity and accel
00340     DOF_GrpIter &theDOFs = myModel->getDOFs();
00341     DOF_Group *dofPtr;
00342     
00343     while ((dofPtr = theDOFs()) != 0)  {
00344         const ID &id = dofPtr->getID();
00345         int idSize = id.Size();
00346         
00347         int i;
00348         const Vector &disp = dofPtr->getCommittedDisp();        
00349         for (i=0; i < idSize; i++)  {
00350             int loc = id(i);
00351             if (loc >= 0)  {
00352                 (*U)(loc) = disp(i);            
00353             }
00354         }
00355         
00356         const Vector &vel = dofPtr->getCommittedVel();
00357         for (i=0; i < idSize; i++)  {
00358             int loc = id(i);
00359             if (loc >= 0)  {
00360                 (*Udot)(loc) = vel(i);
00361             }
00362         }
00363         
00364         const Vector &accel = dofPtr->getCommittedAccel();      
00365         for (i=0; i < idSize; i++)  {
00366             int loc = id(i);
00367             if (loc >= 0)  {
00368                 (*Udotdot)(loc) = accel(i);
00369             }
00370         }
00371     }    
00372     
00373     return 0;
00374 }
00375 
00376 
00377 int AlphaOS::update(const Vector &deltaU)
00378 {
00379     updateCount++;
00380     if (updateCount > 1)  {
00381         opserr << "WARNING AlphaOS::update() - called more than once -";
00382         opserr << " AlphaOS integration scheme requires a LINEAR solution algorithm\n";
00383         return -1;
00384     }
00385     
00386     AnalysisModel *theModel = this->getAnalysisModelPtr();
00387     if (theModel == 0)  {
00388         opserr << "WARNING AlphaOS::update() - no AnalysisModel set\n";
00389         return -1;
00390     }   
00391     
00392     // check domainChanged() has been called, i.e. Ut will not be zero
00393     if (Ut == 0)  {
00394         opserr << "WARNING AlphaOS::update() - domainChange() failed or not called\n";
00395         return -2;
00396     }   
00397     
00398     // check deltaU is of correct size
00399     if (deltaU.Size() != U->Size())  {
00400         opserr << "WARNING AlphaOS::update() - Vectors of incompatible size ";
00401         opserr << " expecting " << U->Size() << " obtained " << deltaU.Size() << "\n";
00402         return -3;
00403     }
00404     
00405     // save the predictor displacements and velocities
00406     (*Upt) = *U;
00407     (*Uptdot) = *Udot;
00408 
00409     //  determine the response at t+deltaT
00410     (*U) += deltaU;
00411 
00412     Udot->addVector(1.0, deltaU, c2);
00413 
00414     Udotdot->addVector(1.0, deltaU, c3);
00415     
00416     // update the response at the DOFs
00417     theModel->setResponse(*U,*Udot,*Udotdot);
00418 //    if (theModel->updateDomain() < 0)  {
00419 //        opserr << "AlphaOS::update() - failed to update the domain\n";
00420 //        return -4;
00421 //    }
00422     
00423     return 0;
00424 }    
00425 
00426 
00427 int AlphaOS::commit(void)
00428 {
00429     AnalysisModel *theModel = this->getAnalysisModelPtr();
00430     if (theModel == 0)  {
00431         opserr << "WARNING AlphaOS::commit() - no AnalysisModel set\n";
00432         return -1;
00433     }
00434         
00435     // set the time to be t+deltaT
00436     double time = theModel->getCurrentDomainTime();
00437     time += (1.0-alpha)*deltaT;
00438     theModel->setCurrentDomainTime(time);
00439     
00440     return theModel->commitDomain();
00441 }    
00442 
00443 
00444 int AlphaOS::sendSelf(int cTag, Channel &theChannel)
00445 {
00446     Vector data(7);
00447     data(0) = alpha;
00448     data(1) = beta;
00449     data(2) = gamma;
00450     data(3) = alphaM;
00451     data(4) = betaK;
00452     data(5) = betaKi;
00453     data(6) = betaKc;
00454     
00455     if (theChannel.sendVector(this->getDbTag(), cTag, data) < 0)  {
00456         opserr << "WARNING AlphaOS::sendSelf() - could not send data\n";
00457         return -1;
00458     }
00459 
00460     return 0;
00461 }
00462 
00463 
00464 int AlphaOS::recvSelf(int cTag, Channel &theChannel, FEM_ObjectBroker &theBroker)
00465 {
00466     Vector data(7);
00467     if (theChannel.recvVector(this->getDbTag(), cTag, data) < 0)  {
00468         opserr << "WARNING AlphaOS::recvSelf() - could not receive data\n";
00469         return -1;
00470     }
00471     
00472     alpha  = data(0);
00473     beta   = data(1);
00474     gamma  = data(2);
00475     alphaM = data(3);
00476     betaK  = data(4);
00477     betaKi = data(5);
00478     betaKc = data(6);
00479     
00480     return 0;
00481 }
00482 
00483 
00484 void AlphaOS::Print(OPS_Stream &s, int flag)
00485 {
00486     AnalysisModel *theModel = this->getAnalysisModelPtr();
00487     if (theModel != 0)  {
00488         double currentTime = theModel->getCurrentDomainTime();
00489         s << "\t AlphaOS - currentTime: " << currentTime << endln;
00490         s << "  alpha: " << alpha << " beta: " << beta  << " gamma: " << gamma << endln;
00491         s << "  c1: " << c1 << " c2: " << c2 << " c3: " << c3 << endln;
00492         s << "  Rayleigh Damping - alphaM: " << alphaM;
00493         s << "  betaK: " << betaK << "   betaKi: " << betaKi << endln;      
00494     } else 
00495         s << "\t AlphaOS - no associated AnalysisModel\n";
00496 }
00497 
00498 
00499 int AlphaOS::formElementResidual(void)
00500 {
00501     // calculate Residual Force     
00502     AnalysisModel *theModel = this->getAnalysisModelPtr();
00503     LinearSOE *theSOE = this->getLinearSOEPtr();
00504     
00505     // loop through the FE_Elements and add the residual
00506     FE_Element *elePtr;
00507     
00508     int res = 0;    
00509     
00510     FE_EleIter &theEles = theModel->getFEs();
00511     while((elePtr = theEles()) != 0)  {
00512         // calculate R-F(d)
00513         if (theSOE->addB(elePtr->getResidual(this),elePtr->getID()) < 0)  {
00514             opserr << "WARNING IncrementalIntegrator::formElementResidual -";
00515             opserr << " failed in addB for ID " << elePtr->getID();
00516             res = -2;
00517         }        
00518         // add Ki*d -> R-F(d)+Ki*d
00519         double tmp_c2 = c2;
00520         double tmp_c3 = c3;
00521         alpha = alpha-1.0;
00522         c2 = c3 = 0.0; // no contribution of C and M to tangent
00523         const Vector Ki_d = elePtr->getTangForce(*Ut - *Upt);
00524         if (theSOE->addB(Ki_d, elePtr->getID())<0)  {
00525             opserr << "WARNING AlphaOS::formElementResidual -";
00526             opserr << " failed in addB for ID " << elePtr->getID();
00527             res = -2;
00528         }
00529         alpha = alpha+1.0;
00530         c2 = tmp_c2;
00531         c3 = tmp_c3;
00532     }
00533 
00534     return res;
00535 }

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