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
00034
00035
00036 #include <Newmark.h>
00037 #include <FE_Element.h>
00038 #include <LinearSOE.h>
00039 #include <AnalysisModel.h>
00040 #include <Vector.h>
00041 #include <DOF_Group.h>
00042 #include <DOF_GrpIter.h>
00043 #include <AnalysisModel.h>
00044 #include <Channel.h>
00045 #include <FEM_ObjectBroker.h>
00046
00047 Newmark::Newmark()
00048 :TransientIntegrator(INTEGRATOR_TAGS_Newmark),
00049 displ(true), gamma(0), beta(0),
00050 rayleighDamping(false), alphaM(0.0), betaK(0.0), betaKi(0.0), betaKc(0.0),
00051 c1(0.0), c2(0.0), c3(0.0),
00052 Ut(0), Utdot(0), Utdotdot(0), U(0), Udot(0), Udotdot(0),
00053 determiningMass(false)
00054 {
00055
00056 }
00057
00058 Newmark::Newmark(double theGamma, double theBeta, bool dispFlag)
00059 :TransientIntegrator(INTEGRATOR_TAGS_Newmark),
00060 displ(dispFlag),
00061 gamma(theGamma), beta(theBeta),
00062 rayleighDamping(false),
00063 alphaM(0.0), betaK(0.0), betaKi(0.0), betaKc(0.0),
00064 c1(0.0), c2(0.0), c3(0.0),
00065 Ut(0), Utdot(0), Utdotdot(0), U(0), Udot(0), Udotdot(0),
00066 determiningMass(false)
00067 {
00068
00069 }
00070
00071 Newmark::Newmark(double theGamma, double theBeta,
00072 double alpham, double betak,
00073 double betaki, double betakc,
00074 bool dispFlag)
00075 :TransientIntegrator(INTEGRATOR_TAGS_Newmark),
00076 displ(dispFlag),
00077 gamma(theGamma), beta(theBeta),
00078 rayleighDamping(true),
00079 alphaM(alpham), betaK(betak), betaKi(betaki), betaKc(betakc),
00080 c1(0.0), c2(0.0), c3(0.0),
00081 Ut(0), Utdot(0), Utdotdot(0), U(0), Udot(0), Udotdot(0),
00082 determiningMass(false)
00083 {
00084 if (alpham == 0.0 && betak == 0.0 && betaki == 0.0 && betakc == 0.0)
00085 rayleighDamping = false;
00086 }
00087
00088 Newmark::~Newmark()
00089 {
00090
00091 if (Ut != 0)
00092 delete Ut;
00093 if (Utdot != 0)
00094 delete Utdot;
00095 if (Utdotdot != 0)
00096 delete Utdotdot;
00097 if (U != 0)
00098 delete U;
00099 if (Udot != 0)
00100 delete Udot;
00101 if (Udotdot != 0)
00102 delete Udotdot;
00103 }
00104
00105
00106 int
00107 Newmark::formEleResidual(FE_Element *theEle)
00108 {
00109 theEle->zeroResidual();
00110 if (rayleighDamping == false) {
00111 theEle->addRIncInertiaToResidual();
00112 } else {
00113 theEle->addRIncInertiaToResidual();
00114 theEle->addKtForce(*Udot, -betaK);
00115 theEle->addKcForce(*Udot, -betaKc);
00116 theEle->addKiForce(*Udot, -betaKi);
00117 theEle->addM_Force(*Udot, -alphaM);
00118 }
00119 return 0;
00120 }
00121
00122 int
00123 Newmark::formNodUnbalance(DOF_Group *theDof)
00124 {
00125 theDof->zeroUnbalance();
00126 if (rayleighDamping == false)
00127 theDof->addPIncInertiaToUnbalance();
00128 else {
00129 theDof->addPIncInertiaToUnbalance();
00130 theDof->addM_Force(*Udot,-alphaM);
00131 }
00132
00133 return 0;
00134 }
00135
00136 int
00137 Newmark::initialize(void)
00138 {
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190 return 0;
00191 }
00192
00193
00194
00195 int
00196 Newmark::newStep(double deltaT)
00197 {
00198 if (beta == 0 || gamma == 0 ) {
00199 cerr << "Newton::newStep() - error in variable\n";
00200 cerr << "gamma = " << gamma << " beta= " << beta << endl;
00201 return -1;
00202 }
00203
00204
00205
00206 AnalysisModel *theModel = this->getAnalysisModelPtr();
00207
00208
00209
00210
00211 if (rayleighDamping == true && betaKc != 0.0) {
00212 FE_Element *elePtr;
00213 FE_EleIter &theEles = theModel->getFEs();
00214 while((elePtr = theEles()) != 0)
00215 elePtr->setKc();
00216 }
00217
00218 if (displ == true) {
00219 if (deltaT <= 0.0) {
00220 cerr << "Newton::newStep() - error in variable\n";
00221 cerr << "dT = " << deltaT << endl;
00222 return -2;
00223 }
00224 c1 = 1.0;
00225 c2 = gamma/(beta*deltaT);
00226 c3 = 1.0/(beta*deltaT*deltaT);
00227 } else {
00228 c1 = beta*deltaT*deltaT;
00229 c2 = gamma*deltaT;
00230 c3 = 1.0;
00231 }
00232
00233 if (U == 0) {
00234 cerr << "Newton::newStep() - domainChange() failed or hasn't been called\n";
00235 return -3;
00236 }
00237
00238
00239 (*Ut) = *U;
00240 (*Utdot) = *Udot;
00241 (*Utdotdot) = *Udotdot;
00242
00243 if (displ == true) {
00244
00245
00246 double a1 = (1.0 - gamma/beta);
00247 double a2 = (deltaT)*(1.0 - 0.5*gamma/beta);
00248
00249 Udot->addVector(a1, *Utdotdot,a2);
00250
00251 double a3 = -1.0/(beta*deltaT);
00252 double a4 = 1 - 0.5/beta;
00253
00254 Udotdot->addVector(a4, *Utdot,a3);
00255
00256 } else {
00257
00258 double a1 = (deltaT*deltaT/2.0);
00259 U->addVector(1.0, *Utdot,deltaT);
00260 U->addVector(1.0, *Utdotdot,a1);
00261
00262 Udot->addVector(1.0, *Utdotdot,deltaT);
00263 }
00264
00265
00266 theModel->setResponse(*U,*Udot,*Udotdot);
00267
00268
00269 double time = theModel->getCurrentDomainTime();
00270 time +=deltaT;
00271 theModel->applyLoadDomain(time);
00272
00273 theModel->updateDomain();
00274
00275 return 0;
00276 }
00277
00278
00279
00280 int
00281 Newmark::revertToLastStep()
00282 {
00283
00284 if (U != 0) {
00285 (*U) = *Ut;
00286 (*Udot) = *Utdot;
00287 (*Udotdot) = *Utdotdot;
00288 }
00289 return 0;
00290 }
00291
00292
00293 int
00294 Newmark::formEleTangent(FE_Element *theEle)
00295 {
00296 if (determiningMass == true)
00297 return 0;
00298
00299 theEle->zeroTangent();
00300
00301 if (statusFlag == CURRENT_TANGENT) {
00302 if (rayleighDamping == false) {
00303 theEle->addKtToTang(c1);
00304 theEle->addCtoTang(c2);
00305 theEle->addMtoTang(c3);
00306 } else {
00307 theEle->addKtToTang(c1 + c2*betaK);
00308 theEle->addMtoTang(c3 + c2*alphaM);
00309 theEle->addKiToTang(c2*betaKi);
00310 theEle->addKcToTang(c2*betaKc);
00311 }
00312 } else if (statusFlag == INITIAL_TANGENT) {
00313 if (rayleighDamping == false) {
00314 theEle->addKiToTang(c1);
00315 theEle->addCtoTang(c2);
00316 theEle->addMtoTang(c3);
00317 } else {
00318 theEle->addKtToTang(c2*betaK);
00319 theEle->addMtoTang(c3 + c2*alphaM);
00320 theEle->addKiToTang(c1 + c2*betaKi);
00321 theEle->addKcToTang(c2*betaKc);
00322 }
00323 } else if (statusFlag == CURRENT_SECANT) {
00324 if (rayleighDamping == false) {
00325 theEle->addKsToTang(c1);
00326 theEle->addCtoTang(c2);
00327 theEle->addMtoTang(c3);
00328 } else {
00329 theEle->addKsToTang(c1 + c2*betaK);
00330 theEle->addMtoTang(c3 + c2*alphaM);
00331 theEle->addKiToTang(c2*betaKi);
00332 theEle->addKcToTang(c2*betaKc);
00333 }
00334 }
00335
00336 return 0;
00337 }
00338
00339
00340 int
00341 Newmark::formNodTangent(DOF_Group *theDof)
00342 {
00343 if (determiningMass == true)
00344 return 0;
00345
00346 theDof->zeroTangent();
00347 if (rayleighDamping == false)
00348 theDof->addMtoTang(c3);
00349 else
00350 theDof->addMtoTang(c3 + c2*alphaM);
00351
00352 return(0);
00353 }
00354
00355
00356
00357 int
00358 Newmark::domainChanged()
00359 {
00360 AnalysisModel *myModel = this->getAnalysisModelPtr();
00361 LinearSOE *theLinSOE = this->getLinearSOEPtr();
00362 const Vector &x = theLinSOE->getX();
00363 int size = x.Size();
00364
00365
00366 if (Ut == 0 || Ut->Size() != size) {
00367
00368
00369 if (Ut != 0)
00370 delete Ut;
00371 if (Utdot != 0)
00372 delete Utdot;
00373 if (Utdotdot != 0)
00374 delete Utdotdot;
00375 if (U != 0)
00376 delete U;
00377 if (Udot != 0)
00378 delete Udot;
00379 if (Udotdot != 0)
00380 delete Udotdot;
00381
00382
00383 Ut = new Vector(size);
00384 Utdot = new Vector(size);
00385 Utdotdot = new Vector(size);
00386 U = new Vector(size);
00387 Udot = new Vector(size);
00388 Udotdot = new Vector(size);
00389
00390
00391 if (Ut == 0 || Ut->Size() != size ||
00392 Utdot == 0 || Utdot->Size() != size ||
00393 Utdotdot == 0 || Utdotdot->Size() != size ||
00394 U == 0 || U->Size() != size ||
00395 Udot == 0 || Udot->Size() != size ||
00396 Udotdot == 0 || Udotdot->Size() != size) {
00397
00398 cerr << "Newmark::domainChanged - ran out of memory\n";
00399
00400
00401 if (Ut != 0)
00402 delete Ut;
00403 if (Utdot != 0)
00404 delete Utdot;
00405 if (Utdotdot != 0)
00406 delete Utdotdot;
00407 if (U != 0)
00408 delete U;
00409 if (Udot != 0)
00410 delete Udot;
00411 if (Udotdot != 0)
00412 delete Udotdot;
00413
00414 Ut = 0; Utdot = 0; Utdotdot = 0;
00415 U = 0; Udot = 0; Udotdot = 0;
00416 return -1;
00417 }
00418 }
00419
00420
00421
00422
00423 DOF_GrpIter &theDOFs = myModel->getDOFs();
00424 DOF_Group *dofPtr;
00425
00426 while ((dofPtr = theDOFs()) != 0) {
00427 const ID &id = dofPtr->getID();
00428 int idSize = id.Size();
00429
00430
00431 int i;
00432 const Vector &disp = dofPtr->getCommittedDisp();
00433 for (i=0; i < idSize; i++) {
00434 int loc = id(i);
00435 if (loc >= 0) {
00436 (*U)(loc) = disp(i);
00437 }
00438 }
00439
00440 const Vector &vel = dofPtr->getCommittedVel();
00441 for (i=0; i < idSize; i++) {
00442 int loc = id(i);
00443 if (loc >= 0) {
00444 (*Udot)(loc) = vel(i);
00445 }
00446 }
00447
00448 const Vector &accel = dofPtr->getCommittedAccel();
00449 for (i=0; i < idSize; i++) {
00450 int loc = id(i);
00451 if (loc >= 0) {
00452 (*Udotdot)(loc) = accel(i);
00453 }
00454 }
00466 }
00467
00468 return 0;
00469 }
00470
00471
00472 int
00473 Newmark::update(const Vector &deltaU)
00474 {
00475 AnalysisModel *theModel = this->getAnalysisModelPtr();
00476 if (theModel == 0) {
00477 cerr << "WARNING Newmark::update() - no AnalysisModel set\n";
00478 return -1;
00479 }
00480
00481
00482 if (Ut == 0) {
00483 cerr << "WARNING Newmark::update() - domainChange() failed or not called\n";
00484 return -2;
00485 }
00486
00487
00488 if (deltaU.Size() != U->Size()) {
00489 cerr << "WARNING Newmark::update() - Vectors of incompatable size ";
00490 cerr << " expecting " << U->Size() << " obtained " << deltaU.Size() << endl;
00491 return -3;
00492 }
00493
00494
00495 if (displ == true) {
00496 (*U) += deltaU;
00497 Udot->addVector(1.0, deltaU,c2);
00498 Udotdot->addVector(1.0, deltaU,c3);
00499 } else {
00500 (*Udotdot) += deltaU;
00501 U->addVector(1.0, deltaU,c1);
00502 Udot->addVector(1.0, deltaU,c2);
00503 }
00504
00505
00506 theModel->setResponse(*U,*Udot,*Udotdot);
00507 theModel->updateDomain();
00508
00509 return 0;
00510 }
00511
00512 int
00513 Newmark::sendSelf(int cTag, Channel &theChannel)
00514 {
00515 Vector data(8);
00516 data(0) = gamma;
00517 data(1) = beta;
00518 if (displ == true)
00519 data(2) = 1.0;
00520 else
00521 data(2) = 0.0;
00522 if (rayleighDamping == true) {
00523 data(3) = 1.0;
00524 data(4) = alphaM;
00525 data(5) = betaK;
00526 data(6) = betaKi;
00527 data(7) = betaKc;
00528 } else
00529 data(3) = 0.0;
00530
00531 if (theChannel.sendVector(this->getDbTag(), cTag, data) < 0) {
00532 cerr << "WARNING Newmark::sendSelf() - could not send data\n";
00533 return -1;
00534 }
00535 return 0;
00536 }
00537
00538 int
00539 Newmark::recvSelf(int cTag, Channel &theChannel, FEM_ObjectBroker &theBroker)
00540 {
00541 Vector data(8);
00542 if (theChannel.recvVector(this->getDbTag(), cTag, data) < 0) {
00543 cerr << "WARNING Newmark::recvSelf() - could not receive data\n";
00544 gamma = 0.5; beta = 0.25; rayleighDamping = false;
00545 return -1;
00546 }
00547
00548 gamma = data(0);
00549 beta = data(1);
00550 if (data(2) == 1.0)
00551 displ = true;
00552 else
00553 displ = false;
00554 if (data(3) == 1.0) {
00555 rayleighDamping = true;
00556 alphaM = data(4);
00557 betaK = data(5);
00558 betaKi = data(6);
00559 betaKc = data(7);
00560 } else
00561 rayleighDamping = false;
00562
00563 return 0;
00564
00565 }
00566
00567 void
00568 Newmark::Print(ostream &s, int flag)
00569 {
00570 AnalysisModel *theModel = this->getAnalysisModelPtr();
00571 if (theModel != 0) {
00572 double currentTime = theModel->getCurrentDomainTime();
00573 s << "\t Newmark - currentTime: " << currentTime;
00574 s << " gamma: " << gamma << " beta: " << beta << endl;
00575 s << " c1: " << c1 << " c2: " << c2 << " c3: " << c3 << endl;
00576 if (rayleighDamping == true) {
00577 s << " Rayleigh Damping - alphaM: " << alphaM;
00578 s << " betaK: " << betaK << endl;
00579 }
00580 } else
00581 s << "\t Newmark - no associated AnalysisModel\n";
00582 }
00583