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