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 #include <ElasticBeam2d.h>
00036 #include <Domain.h>
00037 #include <Channel.h>
00038 #include <FEM_ObjectBroker.h>
00039
00040 #include <CrdTransf2d.h>
00041 #include <Information.h>
00042 #include <ElementResponse.h>
00043 #include <Renderer.h>
00044
00045 #include <math.h>
00046 #include <stdlib.h>
00047
00048 Matrix ElasticBeam2d::K(6,6);
00049 Vector ElasticBeam2d::P(6);
00050 Matrix ElasticBeam2d::kb(3,3);
00051
00052 ElasticBeam2d::ElasticBeam2d()
00053 :Element(0,ELE_TAG_ElasticBeam2d),
00054 A(0), E(0), I(0), L(0.0), rho(0.0), Q(6), q(3),
00055 connectedExternalNodes(2), theCoordTransf(0)
00056 {
00057
00058 }
00059
00060 ElasticBeam2d::ElasticBeam2d(int tag, double a, double e, double i,
00061 int Nd1, int Nd2,
00062 CrdTransf2d &coordTransf, double r)
00063 :Element(tag,ELE_TAG_ElasticBeam2d),
00064 A(a), E(e), I(i), L(0.0), rho(r), Q(6), q(3),
00065 connectedExternalNodes(2), theCoordTransf(0)
00066 {
00067 connectedExternalNodes(0) = Nd1;
00068 connectedExternalNodes(1) = Nd2;
00069
00070 theCoordTransf = coordTransf.getCopy();
00071
00072 if (!theCoordTransf)
00073 g3ErrorHandler->fatal("ElasticBeam2d::ElasticBeam2d -- failed to get copy of coordinate transformation");
00074 }
00075
00076 ElasticBeam2d::~ElasticBeam2d()
00077 {
00078 if (theCoordTransf)
00079 delete theCoordTransf;
00080 }
00081
00082 int
00083 ElasticBeam2d::getNumExternalNodes(void) const
00084 {
00085 return 2;
00086 }
00087
00088 const ID &
00089 ElasticBeam2d::getExternalNodes(void)
00090 {
00091 return connectedExternalNodes;
00092 }
00093
00094 int
00095 ElasticBeam2d::getNumDOF(void)
00096 {
00097 return 6;
00098 }
00099
00100 void
00101 ElasticBeam2d::setDomain(Domain *theDomain)
00102 {
00103 if (theDomain == 0)
00104 g3ErrorHandler->fatal("ElasticBeam2d::setDomain -- Domain is null");
00105
00106 node1Ptr = theDomain->getNode(connectedExternalNodes(0));
00107 node2Ptr = theDomain->getNode(connectedExternalNodes(1));
00108
00109 if (node1Ptr == 0)
00110 g3ErrorHandler->fatal("ElasticBeam2d::setDomain -- Node 1: %i does not exist",
00111 connectedExternalNodes(0));
00112
00113 if (node2Ptr == 0)
00114 g3ErrorHandler->fatal("ElasticBeam2d::setDomain -- Node 2: %i does not exist",
00115 connectedExternalNodes(1));
00116
00117 int dofNd1 = node1Ptr->getNumberDOF();
00118 int dofNd2 = node2Ptr->getNumberDOF();
00119
00120 if (dofNd1 != 3)
00121 g3ErrorHandler->fatal("ElasticBeam2d::setDomain -- Node 1: %i has incorrect number of DOF",
00122 connectedExternalNodes(0));
00123
00124 if (dofNd2 != 3)
00125 g3ErrorHandler->fatal("ElasticBeam2d::setDomain -- Node 2: %i has incorrect number of DOF",
00126 connectedExternalNodes(1));
00127
00128 this->DomainComponent::setDomain(theDomain);
00129
00130 if (theCoordTransf->initialize(node1Ptr, node2Ptr) != 0)
00131 g3ErrorHandler->fatal("ElasticBeam2d::setDomain -- Error initializing coordinate transformation");
00132
00133 L = theCoordTransf->getInitialLength();
00134
00135 if (L == 0.0)
00136 g3ErrorHandler->fatal("ElasticBeam2d::setDomain -- Element has zero length");
00137 }
00138
00139 int
00140 ElasticBeam2d::commitState()
00141 {
00142 return theCoordTransf->commitState();
00143 }
00144
00145 int
00146 ElasticBeam2d::revertToLastCommit()
00147 {
00148 return theCoordTransf->revertToLastCommit();
00149 }
00150
00151 int
00152 ElasticBeam2d::revertToStart()
00153 {
00154 return theCoordTransf->revertToStart();
00155 }
00156
00157 const Matrix &
00158 ElasticBeam2d::getTangentStiff(void)
00159 {
00160 theCoordTransf->update();
00161
00162 const Vector &v = theCoordTransf->getBasicTrialDisp();
00163
00164 double EoverL = E/L;
00165 double EAoverL = A*EoverL;
00166 double EIoverL2 = 2.0*I*EoverL;
00167 double EIoverL4 = 2.0*EIoverL2;
00168
00169 q(0) = EAoverL*v(0);
00170 q(1) = EIoverL4*v(1) + EIoverL2*v(2);
00171 q(2) = EIoverL2*v(1) + EIoverL4*v(2);
00172
00173 kb(0,0) = EAoverL;
00174 kb(1,1) = kb(2,2) = EIoverL4;
00175 kb(2,1) = kb(1,2) = EIoverL2;
00176
00177 return theCoordTransf->getGlobalStiffMatrix(kb,q);
00178 }
00179
00180 const Matrix &
00181 ElasticBeam2d::getSecantStiff(void)
00182 {
00183 return this->getTangentStiff();
00184 }
00185
00186 const Matrix &
00187 ElasticBeam2d::getDamp(void)
00188 {
00189 K.Zero();
00190
00191 return K;
00192 }
00193
00194 const Matrix &
00195 ElasticBeam2d::getMass(void)
00196 {
00197 K.Zero();
00198
00199 if (rho > 0.0) {
00200 double m = 0.5*rho*L;
00201
00202 K(0,0) = m;
00203 K(1,1) = m;
00204
00205 K(3,3) = m;
00206 K(4,4) = m;
00207 }
00208
00209 return K;
00210 }
00211
00212 void
00213 ElasticBeam2d::zeroLoad(void)
00214 {
00215 Q.Zero();
00216
00217 return;
00218 }
00219
00220 int
00221 ElasticBeam2d::addLoad(const Vector &moreLoad)
00222 {
00223 if (moreLoad.Size() != 6) {
00224 g3ErrorHandler->warning("ElasticBeam2d::addLoad: vector not of correct size");
00225 return -1;
00226 }
00227
00228
00229 Q.addVector(1.0, moreLoad, 1.0);
00230
00231 return 0;
00232 }
00233
00234 int
00235 ElasticBeam2d::addInertiaLoadToUnbalance(const Vector &accel)
00236 {
00237 if (rho == 0.0)
00238 return 0;
00239
00240
00241 const Vector &Raccel1 = node1Ptr->getRV(accel);
00242 const Vector &Raccel2 = node2Ptr->getRV(accel);
00243
00244 if (3 != Raccel1.Size() || 3 != Raccel2.Size()) {
00245 g3ErrorHandler->warning("ElasticBeam2d::addInertiaLoadToUnbalance %s\n",
00246 "matrix and vector sizes are incompatable");
00247 return -1;
00248 }
00249
00250
00251
00252
00253 double m = 0.5*rho*L;
00254
00255 Q(0) += -m * Raccel1(0);
00256 Q(1) += -m * Raccel1(1);
00257
00258 Q(3) += -m * Raccel2(0);
00259 Q(4) += -m * Raccel2(1);
00260
00261 return 0;
00262 }
00263
00264 const Vector &
00265 ElasticBeam2d::getResistingForceIncInertia()
00266 {
00267 P = this->getResistingForce();
00268
00269 const Vector &accel1 = node1Ptr->getTrialAccel();
00270 const Vector &accel2 = node2Ptr->getTrialAccel();
00271
00272 double m = 0.5*rho*L;
00273
00274 P(0) += m * accel1(0);
00275 P(1) += m * accel1(1);
00276
00277 P(3) += m * accel2(0);
00278 P(4) += m * accel2(1);
00279
00280 return P;
00281 }
00282
00283 const Vector &
00284 ElasticBeam2d::getResistingForce()
00285 {
00286 theCoordTransf->update();
00287
00288 const Vector &v = theCoordTransf->getBasicTrialDisp();
00289
00290 double EoverL = E/L;
00291 double EAoverL = A*EoverL;
00292 double EIoverL2 = 2.0*I*EoverL;
00293 double EIoverL4 = 2.0*EIoverL2;
00294
00295 q(0) = EAoverL*v(0);
00296 q(1) = EIoverL4*v(1) + EIoverL2*v(2);
00297 q(2) = EIoverL2*v(1) + EIoverL4*v(2);
00298
00299 static Vector dummy(2);
00300
00301 P = theCoordTransf->getGlobalResistingForce(q, dummy);
00302
00303
00304 P.addVector(1.0, Q, -1.0);
00305
00306 return P;
00307 }
00308
00309 int
00310 ElasticBeam2d::sendSelf(int cTag, Channel &theChannel)
00311 {
00312 int res = 0;
00313
00314 static Vector data(9);
00315
00316 data(0) = A;
00317 data(1) = E;
00318 data(2) = I;
00319 data(3) = rho;
00320 data(4) = this->getTag();
00321 data(5) = connectedExternalNodes(0);
00322 data(6) = connectedExternalNodes(1);
00323 data(7) = theCoordTransf->getClassTag();
00324
00325 int dbTag = theCoordTransf->getDbTag();
00326
00327 if (dbTag == 0) {
00328 dbTag = theChannel.getDbTag();
00329 if (dbTag != 0)
00330 theCoordTransf->setDbTag(dbTag);
00331 }
00332
00333 data(8) = dbTag;
00334
00335
00336 res += theChannel.sendVector(this->getDbTag(), cTag, data);
00337 if (res < 0) {
00338 g3ErrorHandler->warning("%s -- could not send data Vector",
00339 "ElasticBeam2d::sendSelf");
00340 return res;
00341 }
00342
00343
00344 res += theCoordTransf->sendSelf(cTag, theChannel);
00345 if (res < 0) {
00346 g3ErrorHandler->warning("%s -- could not send CoordTransf",
00347 "ElasticBeam2d::sendSelf");
00348 return res;
00349 }
00350
00351 return res;
00352 }
00353
00354 int
00355 ElasticBeam2d::recvSelf(int cTag, Channel &theChannel, FEM_ObjectBroker &theBroker)
00356 {
00357 int res = 0;
00358
00359 static Vector data(9);
00360
00361 res += theChannel.recvVector(this->getDbTag(), cTag, data);
00362 if (res < 0) {
00363 g3ErrorHandler->warning("%s -- could not receive data Vector",
00364 "ElasticBeam2d::recvSelf");
00365 return res;
00366 }
00367
00368 A = data(0);
00369 E = data(1);
00370 I = data(2);
00371 rho = data(3);
00372 this->setTag((int)data(4));
00373 connectedExternalNodes(0) = (int)data(5);
00374 connectedExternalNodes(1) = (int)data(6);
00375
00376
00377 int crdTag = (int)data(7);
00378 if (theCoordTransf == 0) {
00379 theCoordTransf = theBroker.getNewCrdTransf2d(crdTag);
00380 if (theCoordTransf == 0) {
00381 g3ErrorHandler->warning("%s -- could not get a CrdTransf2d",
00382 "ElasticBeam2d::recvSelf");
00383 return -1;
00384 }
00385 }
00386
00387
00388
00389 if (theCoordTransf->getClassTag() != crdTag) {
00390 delete theCoordTransf;
00391 theCoordTransf = theBroker.getNewCrdTransf2d(crdTag);
00392 if (theCoordTransf == 0) {
00393 g3ErrorHandler->warning("%s -- could not get a CrdTransf2d",
00394 "ElasticBeam2d::recvSelf");
00395 return -1;
00396 }
00397 }
00398
00399
00400 theCoordTransf->setDbTag((int)data(8));
00401 res += theCoordTransf->recvSelf(cTag, theChannel, theBroker);
00402 if (res < 0) {
00403 g3ErrorHandler->warning("%s -- could not receive CoordTransf",
00404 "ElasticBeam2d::recvSelf");
00405 return res;
00406 }
00407
00408
00409 theCoordTransf->revertToLastCommit();
00410
00411 return res;
00412 }
00413
00414 void
00415 ElasticBeam2d::Print(ostream &s, int flag)
00416 {
00417 s << "\nElasticBeam2d: " << this->getTag() << endl;
00418 s << "\tConnected Nodes: " << connectedExternalNodes ;
00419 s << "\tCoordTransf: " << theCoordTransf->getTag() << endl;
00420 }
00421
00422 int
00423 ElasticBeam2d::displaySelf(Renderer &theViewer, int displayMode, float fact)
00424 {
00425
00426
00427 const Vector &end1Crd = node1Ptr->getCrds();
00428 const Vector &end2Crd = node2Ptr->getCrds();
00429
00430 const Vector &end1Disp = node1Ptr->getDisp();
00431 const Vector &end2Disp = node2Ptr->getDisp();
00432
00433 static Vector v1(3);
00434 static Vector v2(3);
00435
00436 for (int i = 0; i < 2; i++) {
00437 v1(i) = end1Crd(i) + end1Disp(i)*fact;
00438 v2(i) = end2Crd(i) + end2Disp(i)*fact;
00439 }
00440
00441 return theViewer.drawLine (v1, v2, 1.0, 1.0);
00442 }
00443
00444 Response*
00445 ElasticBeam2d::setResponse(char **argv, int argc, Information &info)
00446 {
00447
00448 if (strcmp(argv[0],"stiffness") == 0)
00449 return new ElementResponse(this, 1, K);
00450
00451
00452 else if (strcmp(argv[0],"force") == 0 || strcmp(argv[0],"forces") == 0 ||
00453 strcmp(argv[0],"globalForce") == 0 || strcmp(argv[0],"globalForces") == 0)
00454 return new ElementResponse(this, 2, P);
00455
00456
00457 else if (strcmp(argv[0],"localForce") == 0 || strcmp(argv[0],"localForces") == 0)
00458 return new ElementResponse(this, 3, P);
00459
00460 else
00461 return 0;
00462 }
00463
00464 int
00465 ElasticBeam2d::getResponse (int responseID, Information &eleInfo)
00466 {
00467 double V;
00468
00469 switch (responseID) {
00470 case 1:
00471 return eleInfo.setMatrix(this->getTangentStiff());
00472
00473 case 2:
00474 return eleInfo.setVector(this->getResistingForce());
00475
00476 case 3:
00477
00478 P(3) = q(0);
00479 P(0) = -q(0);
00480
00481 P(2) = q(1);
00482 P(5) = q(2);
00483
00484 V = (q(1)+q(2))/L;
00485 P(1) = V;
00486 P(4) = -V;
00487 return eleInfo.setVector(P);
00488
00489 default:
00490 return -1;
00491 }
00492 }
00493
00494 int
00495 ElasticBeam2d::setParameter (char **argv, int argc, Information &info)
00496 {
00497
00498 if (strcmp(argv[0],"E") == 0) {
00499 info.theType = DoubleType;
00500 return 1;
00501 }
00502
00503
00504 else if (strcmp(argv[0],"A") == 0) {
00505 info.theType = DoubleType;
00506 return 2;
00507 }
00508
00509
00510 else if (strcmp(argv[0],"I") == 0) {
00511 info.theType = DoubleType;
00512 return 3;
00513 }
00514
00515 else
00516 return -1;
00517 }
00518
00519 int
00520 ElasticBeam2d::updateParameter (int parameterID, Information &info)
00521 {
00522 switch (parameterID) {
00523 case -1:
00524 return -1;
00525 case 1:
00526 this->E = info.theDouble;
00527 return 0;
00528 case 2:
00529 this->A = info.theDouble;
00530 return 0;
00531 case 3:
00532 this->I = info.theDouble;
00533 return 0;
00534 default:
00535 return -1;
00536 }
00537 }