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 <Newmark1.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 Newmark1::Newmark1()
00048 :TransientIntegrator(INTEGRATOR_TAGS_Newmark1),
00049 gamma(0), beta(0),
00050 alphaM(0.0), betaK(0.0), betaKi(0.0),
00051 c1(0.0), c2(0.0), c3(0.0), c4(0.0),
00052 Up(0), Updot(0), U(0), Udot(0), Udotdot(0)
00053 {
00054
00055 }
00056
00057 Newmark1::Newmark1(double theGamma, double theBeta, bool dispFlag)
00058 :TransientIntegrator(INTEGRATOR_TAGS_Newmark1),
00059 gamma(theGamma), beta(theBeta),
00060 alphaM(0.0), betaK(0.0), betaKi(0.0), betaKc(0.0),
00061 c1(0.0), c2(0.0), c3(0.0), c4(0.0),
00062 Up(0), Updot(0), U(0), Udot(0), Udotdot(0)
00063 {
00064
00065 }
00066
00067 Newmark1::Newmark1(double theGamma, double theBeta,
00068 double alpham, double betak, double betaki , double betakc)
00069 :TransientIntegrator(INTEGRATOR_TAGS_Newmark1),
00070 gamma(theGamma), beta(theBeta),
00071 alphaM(alpham), betaK(betak), betaKi(betaki), betaKc(betakc),
00072 c1(0.0), c2(0.0), c3(0.0), c4(0.0),
00073 Up(0), Updot(0), U(0), Udot(0), Udotdot(0)
00074 {
00075
00076 }
00077
00078 Newmark1::~Newmark1()
00079 {
00080
00081 if (Up != 0)
00082 delete Up;
00083 if (Updot != 0)
00084 delete Updot;
00085 if (U != 0)
00086 delete U;
00087 if (Udot != 0)
00088 delete Udot;
00089 if (Udotdot != 0)
00090 delete Udotdot;
00091 }
00092
00093
00094 int
00095 Newmark1::initialize(void)
00096 {
00097 return 0;
00098 }
00099
00100 int
00101 Newmark1::newStep(double deltaT)
00102 {
00103
00104 if (beta == 0 || gamma == 0 ) {
00105 opserr << "Newton::newStep() - error in variable\n";
00106 opserr << "gamma = " << gamma << " beta= " << beta << endln;
00107 return -1;
00108 }
00109
00110 if (deltaT <= 0.0) {
00111 opserr << "Newmark1::newStep() - error in variable\n";
00112 opserr << "dT = " << deltaT << endln;
00113 return -2;
00114 }
00115
00116
00117 c1 = 1.0;
00118 c2 = gamma/(beta*deltaT);
00119 c3 = 1.0/(beta*deltaT*deltaT);
00120 c4 = gamma*deltaT;
00121
00122
00123
00124 AnalysisModel *theModel = this->getAnalysisModelPtr();
00125
00126 if (U == 0) {
00127 opserr << "Newton::newStep() - domainChange() failed or hasn't been called\n";
00128 return -3;
00129 }
00130
00131
00132 U->addVector(1.0, *Udot, deltaT);
00133 double a1 = deltaT * deltaT * (.5 - beta);
00134 U->addVector(1.0, *Udotdot, a1);
00135
00136 double a2 = deltaT * (1 - gamma);
00137 Udot->addVector(1.0, *Udotdot,a2);
00138
00139 Udotdot->Zero();
00140
00141 *Up = *U;
00142 *Updot = *Udot;
00143
00144 theModel->setResponse(*U,*Udot,*Udotdot);
00145
00146
00147 double time = theModel->getCurrentDomainTime();
00148 time +=deltaT;
00149
00150 if (theModel->updateDomain(time, deltaT) < 0) {
00151 opserr << "Newmark1::newStep() - failed to update the domain\n";
00152 return -4;
00153 }
00154
00155 return 0;
00156 }
00157
00158 int
00159 Newmark1::revertToLastStep() {
00160 return this->domainChanged();
00161 }
00162
00163 int
00164 Newmark1::formEleTangent(FE_Element *theEle)
00165 {
00166 theEle->zeroTangent();
00167 if (statusFlag == CURRENT_TANGENT) {
00168 theEle->addKtToTang(c1);
00169 theEle->addCtoTang(c2);
00170 theEle->addMtoTang(c3);
00171 } else if (statusFlag == INITIAL_TANGENT) {
00172 theEle->addKiToTang(c1);
00173 theEle->addCtoTang(c2);
00174 theEle->addMtoTang(c3);
00175 }
00176
00177 return 0;
00178 }
00179
00180
00181 int
00182 Newmark1::formNodTangent(DOF_Group *theDof)
00183 {
00184 theDof->zeroTangent();
00185 theDof->addMtoTang(c3);
00186 theDof->addCtoTang(c2);
00187
00188 return(0);
00189 }
00190
00191
00192
00193 int
00194 Newmark1::domainChanged()
00195 {
00196 AnalysisModel *myModel = this->getAnalysisModelPtr();
00197 LinearSOE *theLinSOE = this->getLinearSOEPtr();
00198 const Vector &x = theLinSOE->getX();
00199 int size = x.Size();
00200
00201
00202 if (alphaM != 0.0 || betaK != 0.0 || betaKi != 0.0 || betaKc != 0.0)
00203 myModel->setRayleighDampingFactors(alphaM, betaK, betaKi, betaKc);
00204
00205
00206 if (U == 0 || U ->Size() != size) {
00207
00208
00209 if (Up != 0)
00210 delete Up;
00211 if (Updot != 0)
00212 delete Updot;
00213 if (U != 0)
00214 delete U;
00215 if (Udot != 0)
00216 delete Udot;
00217 if (Udotdot != 0)
00218 delete Udotdot;
00219
00220
00221 Up = new Vector(size);
00222 Updot = new Vector(size);
00223 U = new Vector(size);
00224 Udot = new Vector(size);
00225 Udotdot = new Vector(size);
00226
00227
00228 if (Up == 0 || Up->Size() != size ||
00229 Updot == 0 || Updot->Size() != size ||
00230 U == 0 || U->Size() != size ||
00231 Udot == 0 || Udot->Size() != size ||
00232 Udotdot == 0 || Udotdot->Size() != size) {
00233
00234 opserr << "Newmark1::domainChanged - ran out of memory\n";
00235
00236
00237 if (Up != 0)
00238 delete Up;
00239 if (Updot != 0)
00240 delete Updot;
00241 if (U != 0)
00242 delete U;
00243 if (Udot != 0)
00244 delete Udot;
00245 if (Udotdot != 0)
00246 delete Udotdot;
00247
00248 Up = 0; Updot = 0;
00249 U = 0; Udot = 0; Udotdot = 0;
00250 return -1;
00251 }
00252 }
00253
00254
00255
00256
00257 DOF_GrpIter &theDOFs = myModel->getDOFs();
00258 DOF_Group *dofPtr;
00259
00260 while ((dofPtr = theDOFs()) != 0) {
00261 const ID &id = dofPtr->getID();
00262 int idSize = id.Size();
00263
00264
00265 int i;
00266 const Vector &disp = dofPtr->getCommittedDisp();
00267 for (i=0; i < idSize; i++) {
00268 int loc = id(i);
00269 if (loc >= 0) {
00270 (*U)(loc) = disp(i);
00271 }
00272 }
00273
00274 const Vector &vel = dofPtr->getCommittedVel();
00275 for (i=0; i < idSize; i++) {
00276 int loc = id(i);
00277 if (loc >= 0) {
00278 (*Udot)(loc) = vel(i);
00279 }
00280 }
00281
00282 const Vector &accel = dofPtr->getCommittedAccel();
00283 for (i=0; i < idSize; i++) {
00284 int loc = id(i);
00285 if (loc >= 0) {
00286 (*Udotdot)(loc) = accel(i);
00287 }
00288 }
00289
00301 }
00302 return 0;
00303 }
00304
00305
00306 int
00307 Newmark1::update(const Vector &deltaU)
00308 {
00309 AnalysisModel *theModel = this->getAnalysisModelPtr();
00310 if (theModel == 0) {
00311 opserr << "WARNING Newmark1::update() - no AnalysisModel set\n";
00312 return -1;
00313 }
00314
00315
00316 if (U == 0) {
00317 opserr << "WARNING Newmark1::update() - domainChange() failed or not called\n";
00318 return -2;
00319 }
00320
00321
00322 if (deltaU.Size() != U->Size()) {
00323 opserr << "WARNING Newmark1::update() - Vectors of incompatable size ";
00324 opserr << " expecting " << U->Size() << " obtained " << deltaU.Size() << endln;
00325 return -3;
00326 }
00327
00328
00329 (*U) += deltaU;
00330
00331 (*Udotdot) = (*U);
00332 (*Udotdot) -= (*Up);
00333 (*Udotdot) *= c3;
00334
00335 (*Udot) = (*Updot);
00336 Udot->addVector(1.0, *Udotdot,c4);
00337
00338
00339 theModel->setResponse(*U,*Udot,*Udotdot);
00340 if (theModel->updateDomain() < 0) {
00341 opserr << "Newmark1::newStep() - failed to update the domain\n";
00342 return -4;
00343 }
00344
00345 return 0;
00346 }
00347
00348 int
00349 Newmark1::sendSelf(int cTag, Channel &theChannel)
00350 {
00351 Vector data(7);
00352 data(0) = gamma;
00353 data(1) = beta;
00354 data(2) = 1.0;
00355 data(3) = alphaM;
00356 data(4) = betaK;
00357 data(5) = betaKi;
00358 data(6) = betaKc;
00359
00360 if (theChannel.sendVector(this->getDbTag(), cTag, data) < 0) {
00361 opserr << "WARNING Newmark1::sendSelf() - could not send data\n";
00362 return -1;
00363 }
00364 return 0;
00365 }
00366
00367 int
00368 Newmark1::recvSelf(int cTag, Channel &theChannel, FEM_ObjectBroker &theBroker)
00369 {
00370 Vector data(7);
00371 if (theChannel.recvVector(this->getDbTag(), cTag, data) < 0) {
00372 opserr << "WARNING Newmark1::recvSelf() - could not receive data\n";
00373 gamma = 0.5; beta = 0.25;
00374 return -1;
00375 }
00376
00377 gamma = data(0);
00378 beta = data(1);
00379 alphaM = data(3);
00380 betaK = data(4);
00381 betaKi = data(5);
00382 betaKc = data(6);
00383
00384 return 0;
00385
00386 }
00387
00388 void
00389 Newmark1::Print(OPS_Stream &s, int flag)
00390 {
00391 AnalysisModel *theModel = this->getAnalysisModelPtr();
00392 if (theModel != 0) {
00393 double currentTime = theModel->getCurrentDomainTime();
00394 s << "\t Newmark1 - currentTime: " << currentTime;
00395 s << " gamma: " << gamma << " beta: " << beta << endln;
00396 s << " c1: " << c1 << " c2: " << c2 << " c3: " << c3 << endln;
00397 s << " Rayleigh Damping - alphaM: " << alphaM;
00398 s << " betaK: " << betaK << " betaKi: " << betaKi << endln;
00399 } else
00400 s << "\t Newmark1 - no associated AnalysisModel\n";
00401 }
00402
00403
00404
00405