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

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