00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
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
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
00145 AnalysisModel *theModel = this->getAnalysisModelPtr();
00146
00147
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
00158 (*Ut) = *U;
00159 (*Utdot) = *Udot;
00160 (*Utdotdot) = *Udotdot;
00161
00162
00163 double time = theModel->getCurrentDomainTime();
00164 time += alpha*deltaT;
00165
00166 if (theModel->updateDomain(time, deltaT) < 0) {
00167 opserr << "HHT::newStep() - failed to update the domain\n";
00168 return -4;
00169 }
00170
00171
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
00181 (*Ualphadot) = *Utdot;
00182 Ualphadot->addVector((1.0-alpha), *Udot, alpha);
00183
00184
00185 theModel->setVel(*Ualphadot);
00186 theModel->setAccel(*Udotdot);
00187
00188 return 0;
00189 }
00190
00191
00192 int HHT::revertToLastStep()
00193 {
00194
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
00241 if (alphaM != 0.0 || betaK != 0.0 || betaKi != 0.0 || betaKc != 0.0)
00242 myModel->setRayleighDampingFactors(alphaM, betaK, betaKi, betaKc);
00243
00244
00245 if (Ut == 0 || Ut->Size() != size) {
00246
00247
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
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
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
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
00314
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
00361 if (Ut == 0) {
00362 opserr << "WARNING HHT::update() - domainChange() failed or not called\n";
00363 return -2;
00364 }
00365
00366
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
00374 (*U) += deltaU;
00375
00376 Udot->addVector(1.0, deltaU, c2);
00377
00378 Udotdot->addVector(1.0, deltaU, c3);
00379
00380
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
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
00407 theModel->setResponse(*U,*Udot,*Udotdot);
00408
00409
00410
00411
00412
00413
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 }