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