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 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 alphaM(0.0), betaK(0.0), betaKi(0.0), betaKc(0.0),
00063 c1(0.0), c2(0.0), c3(0.0),
00064 Ut(0), Utdot(0), Utdotdot(0), U(0), Udot(0), Udotdot(0),
00065 determiningMass(false)
00066 {
00067
00068 }
00069
00070 Newmark::Newmark(double theGamma, double theBeta,
00071 double alpham, double betak,
00072 double betaki, double betakc,
00073 bool dispFlag)
00074 :TransientIntegrator(INTEGRATOR_TAGS_Newmark),
00075 displ(dispFlag),
00076 gamma(theGamma), beta(theBeta),
00077 alphaM(alpham), betaK(betak), betaKi(betaki), betaKc(betakc),
00078 c1(0.0), c2(0.0), c3(0.0),
00079 Ut(0), Utdot(0), Utdotdot(0), U(0), Udot(0), Udotdot(0),
00080 determiningMass(false)
00081 {
00082
00083 }
00084
00085 Newmark::~Newmark()
00086 {
00087
00088 if (Ut != 0)
00089 delete Ut;
00090 if (Utdot != 0)
00091 delete Utdot;
00092 if (Utdotdot != 0)
00093 delete Utdotdot;
00094 if (U != 0)
00095 delete U;
00096 if (Udot != 0)
00097 delete Udot;
00098 if (Udotdot != 0)
00099 delete Udotdot;
00100 }
00101
00102
00103
00104
00105
00106 int
00107 Newmark::newStep(double deltaT)
00108 {
00109 if (beta == 0 || gamma == 0 ) {
00110 opserr << "Newton::newStep() - error in variable\n";
00111 opserr << "gamma = " << gamma << " beta= " << beta << endln;
00112 return -1;
00113 }
00114
00115
00116
00117 AnalysisModel *theModel = this->getAnalysisModelPtr();
00118
00119 if (displ == true) {
00120 if (deltaT <= 0.0) {
00121 opserr << "Newton::newStep() - error in variable\n";
00122 opserr << "dT = " << deltaT << endln;
00123 return -2;
00124 }
00125 c1 = 1.0;
00126 c2 = gamma/(beta*deltaT);
00127 c3 = 1.0/(beta*deltaT*deltaT);
00128 } else {
00129 c1 = beta*deltaT*deltaT;
00130 c2 = gamma*deltaT;
00131 c3 = 1.0;
00132 }
00133
00134 if (U == 0) {
00135 opserr << "Newton::newStep() - domainChange() failed or hasn't been called\n";
00136 return -3;
00137 }
00138
00139
00140 (*Ut) = *U;
00141 (*Utdot) = *Udot;
00142 (*Utdotdot) = *Udotdot;
00143
00144 if (displ == true) {
00145
00146
00147 double a1 = (1.0 - gamma/beta);
00148 double a2 = (deltaT)*(1.0 - 0.5*gamma/beta);
00149
00150 Udot->addVector(a1, *Utdotdot,a2);
00151
00152 double a3 = -1.0/(beta*deltaT);
00153 double a4 = 1 - 0.5/beta;
00154
00155 Udotdot->addVector(a4, *Utdot,a3);
00156
00157 } else {
00158
00159 double a1 = (deltaT*deltaT/2.0);
00160 U->addVector(1.0, *Utdot,deltaT);
00161 U->addVector(1.0, *Utdotdot,a1);
00162
00163 Udot->addVector(1.0, *Utdotdot,deltaT);
00164 }
00165
00166
00167 theModel->setResponse(*U,*Udot,*Udotdot);
00168
00169
00170 double time = theModel->getCurrentDomainTime();
00171 time +=deltaT;
00172 if (theModel->updateDomain(time, deltaT) < 0) {
00173 opserr << "Newmark::newStep() - failed to update the domain\n";
00174 return -4;
00175 }
00176
00177 return 0;
00178 }
00179
00180
00181
00182 int
00183 Newmark::revertToLastStep()
00184 {
00185
00186 if (U != 0) {
00187 (*U) = *Ut;
00188 (*Udot) = *Utdot;
00189 (*Udotdot) = *Utdotdot;
00190 }
00191 return 0;
00192 }
00193
00194
00195 int
00196 Newmark::formEleTangent(FE_Element *theEle)
00197 {
00198 if (determiningMass == true)
00199 return 0;
00200
00201 theEle->zeroTangent();
00202
00203 if (statusFlag == CURRENT_TANGENT) {
00204 theEle->addKtToTang(c1);
00205 theEle->addCtoTang(c2);
00206 theEle->addMtoTang(c3);
00207 } else if (statusFlag == INITIAL_TANGENT) {
00208 theEle->addKiToTang(c1);
00209 theEle->addCtoTang(c2);
00210 theEle->addMtoTang(c3);
00211 }
00212
00213 return 0;
00214 }
00215
00216
00217 int
00218 Newmark::formNodTangent(DOF_Group *theDof)
00219 {
00220 if (determiningMass == true)
00221 return 0;
00222
00223 theDof->zeroTangent();
00224 theDof->addMtoTang(c3);
00225 theDof->addCtoTang(c2);
00226
00227 return(0);
00228 }
00229
00230
00231
00232 int
00233 Newmark::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
00261
00262 Ut = new Vector(size);
00263 Utdot = new Vector(size);
00264 Utdotdot = new Vector(size);
00265 U = new Vector(size);
00266 Udot = new Vector(size);
00267 Udotdot = new Vector(size);
00268
00269
00270 if (Ut == 0 || Ut->Size() != size ||
00271 Utdot == 0 || Utdot->Size() != size ||
00272 Utdotdot == 0 || Utdotdot->Size() != size ||
00273 U == 0 || U->Size() != size ||
00274 Udot == 0 || Udot->Size() != size ||
00275 Udotdot == 0 || Udotdot->Size() != size) {
00276
00277 opserr << "Newmark::domainChanged - ran out of memory\n";
00278
00279
00280 if (Ut != 0)
00281 delete Ut;
00282 if (Utdot != 0)
00283 delete Utdot;
00284 if (Utdotdot != 0)
00285 delete Utdotdot;
00286 if (U != 0)
00287 delete U;
00288 if (Udot != 0)
00289 delete Udot;
00290 if (Udotdot != 0)
00291 delete Udotdot;
00292
00293 Ut = 0; Utdot = 0; Utdotdot = 0;
00294 U = 0; Udot = 0; Udotdot = 0;
00295 return -1;
00296 }
00297 }
00298
00299
00300
00301
00302 DOF_GrpIter &theDOFs = myModel->getDOFs();
00303 DOF_Group *dofPtr;
00304
00305 while ((dofPtr = theDOFs()) != 0) {
00306 const ID &id = dofPtr->getID();
00307 int idSize = id.Size();
00308
00309
00310 int i;
00311 const Vector &disp = dofPtr->getCommittedDisp();
00312 for (i=0; i < idSize; i++) {
00313 int loc = id(i);
00314 if (loc >= 0) {
00315 (*U)(loc) = disp(i);
00316 }
00317 }
00318
00319 const Vector &vel = dofPtr->getCommittedVel();
00320 for (i=0; i < idSize; i++) {
00321 int loc = id(i);
00322 if (loc >= 0) {
00323 (*Udot)(loc) = vel(i);
00324 }
00325 }
00326
00327 const Vector &accel = dofPtr->getCommittedAccel();
00328 for (i=0; i < idSize; i++) {
00329 int loc = id(i);
00330 if (loc >= 0) {
00331 (*Udotdot)(loc) = accel(i);
00332 }
00333 }
00344 }
00345
00346 return 0;
00347 }
00348
00349
00350 int
00351 Newmark::update(const Vector &deltaU)
00352 {
00353 AnalysisModel *theModel = this->getAnalysisModelPtr();
00354 if (theModel == 0) {
00355 opserr << "WARNING Newmark::update() - no AnalysisModel set\n";
00356 return -1;
00357 }
00358
00359
00360 if (Ut == 0) {
00361 opserr << "WARNING Newmark::update() - domainChange() failed or not called\n";
00362 return -2;
00363 }
00364
00365
00366 if (deltaU.Size() != U->Size()) {
00367 opserr << "WARNING Newmark::update() - Vectors of incompatable size ";
00368 opserr << " expecting " << U->Size() << " obtained " << deltaU.Size() << endln;
00369 return -3;
00370 }
00371
00372
00373 if (displ == true) {
00374 (*U) += deltaU;
00375 Udot->addVector(1.0, deltaU,c2);
00376 Udotdot->addVector(1.0, deltaU,c3);
00377 } else {
00378 (*Udotdot) += deltaU;
00379 U->addVector(1.0, deltaU,c1);
00380 Udot->addVector(1.0, deltaU,c2);
00381 }
00382
00383
00384 theModel->setResponse(*U,*Udot,*Udotdot);
00385 if (theModel->updateDomain() < 0) {
00386 opserr << "Newmark::update() - failed to update the domain\n";
00387 return -4;
00388 }
00389
00390 return 0;
00391 }
00392
00393 int
00394 Newmark::sendSelf(int cTag, Channel &theChannel)
00395 {
00396 Vector data(8);
00397 data(0) = gamma;
00398 data(1) = beta;
00399 if (displ == true)
00400 data(2) = 1.0;
00401 else
00402 data(2) = 0.0;
00403
00404 data(3) = 1.0;
00405 data(4) = alphaM;
00406 data(5) = betaK;
00407 data(6) = betaKi;
00408 data(7) = betaKc;
00409
00410 if (theChannel.sendVector(this->getDbTag(), cTag, data) < 0) {
00411 opserr << "WARNING Newmark::sendSelf() - could not send data\n";
00412 return -1;
00413 }
00414 return 0;
00415 }
00416
00417 int
00418 Newmark::recvSelf(int cTag, Channel &theChannel, FEM_ObjectBroker &theBroker)
00419 {
00420 Vector data(8);
00421 if (theChannel.recvVector(this->getDbTag(), cTag, data) < 0) {
00422 opserr << "WARNING Newmark::recvSelf() - could not receive data\n";
00423 gamma = 0.5; beta = 0.25;
00424 return -1;
00425 }
00426
00427 gamma = data(0);
00428 beta = data(1);
00429 if (data(2) == 1.0)
00430 displ = true;
00431 else
00432 displ = false;
00433 alphaM = data(4);
00434 betaK = data(5);
00435 betaKi = data(6);
00436 betaKc = data(7);
00437
00438 return 0;
00439
00440 }
00441
00442 void
00443 Newmark::Print(OPS_Stream &s, int flag)
00444 {
00445 AnalysisModel *theModel = this->getAnalysisModelPtr();
00446 if (theModel != 0) {
00447 double currentTime = theModel->getCurrentDomainTime();
00448 s << "\t Newmark - currentTime: " << currentTime;
00449 s << " gamma: " << gamma << " beta: " << beta << endln;
00450 s << " c1: " << c1 << " c2: " << c2 << " c3: " << c3 << endln;
00451 s << " Rayleigh Damping - alphaM: " << alphaM;
00452 s << " betaK: " << betaK << " betaKi: " << betaKi << endln;
00453 } else
00454 s << "\t Newmark - no associated AnalysisModel\n";
00455 }
00456
00457
00458 int
00459 Newmark::revertToStart()
00460 {
00461 if (Ut != 0)
00462 Ut->Zero();
00463 if (Utdot != 0)
00464 Utdot->Zero();
00465 if (Utdotdot != 0)
00466 Utdotdot->Zero();
00467 if (U != 0)
00468 U->Zero();
00469 if (Udot != 0)
00470 Udot->Zero();
00471 if (Udotdot != 0)
00472 Udotdot->Zero();
00473
00474 return 0;
00475 }
00476
00477