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 <ElementalLoad.h>
00037
00038 #include <Domain.h>
00039 #include <Channel.h>
00040 #include <FEM_ObjectBroker.h>
00041
00042 #include <CrdTransf2d.h>
00043 #include <Information.h>
00044 #include <Parameter.h>
00045 #include <ElementResponse.h>
00046 #include <Renderer.h>
00047
00048 #include <math.h>
00049 #include <stdlib.h>
00050
00051 Matrix ElasticBeam2d::K(6,6);
00052 Vector ElasticBeam2d::P(6);
00053 Matrix ElasticBeam2d::kb(3,3);
00054
00055 ElasticBeam2d::ElasticBeam2d()
00056 :Element(0,ELE_TAG_ElasticBeam2d),
00057 A(0.0), E(0.0), I(0.0), alpha(0.0), d(0.0), rho(0.0),
00058 Q(6), q(3),
00059 connectedExternalNodes(2), theCoordTransf(0)
00060 {
00061
00062 q0[0] = 0.0;
00063 q0[1] = 0.0;
00064 q0[2] = 0.0;
00065
00066 p0[0] = 0.0;
00067 p0[1] = 0.0;
00068 p0[2] = 0.0;
00069
00070
00071 for (int i=0; i<2; i++)
00072 theNodes[i] = 0;
00073 }
00074
00075 ElasticBeam2d::ElasticBeam2d(int tag, double a, double e, double i,
00076 int Nd1, int Nd2,
00077 CrdTransf2d &coordTransf, double Alpha, double depth,
00078 double r)
00079 :Element(tag,ELE_TAG_ElasticBeam2d),
00080 A(a), E(e), I(i), alpha(Alpha), d(depth), rho(r),
00081 Q(6), q(3),
00082 connectedExternalNodes(2), theCoordTransf(0)
00083 {
00084 connectedExternalNodes(0) = Nd1;
00085 connectedExternalNodes(1) = Nd2;
00086
00087 theCoordTransf = coordTransf.getCopy();
00088
00089 if (!theCoordTransf) {
00090 opserr << "ElasticBeam2d::ElasticBeam2d -- failed to get copy of coordinate transformation\n";
00091 exit(01);
00092 }
00093
00094 q0[0] = 0.0;
00095 q0[1] = 0.0;
00096 q0[2] = 0.0;
00097
00098 p0[0] = 0.0;
00099 p0[1] = 0.0;
00100 p0[2] = 0.0;
00101
00102
00103 theNodes[0] = 0;
00104 theNodes[1] = 0;
00105 }
00106
00107 ElasticBeam2d::~ElasticBeam2d()
00108 {
00109 if (theCoordTransf)
00110 delete theCoordTransf;
00111 }
00112
00113 int
00114 ElasticBeam2d::getNumExternalNodes(void) const
00115 {
00116 return 2;
00117 }
00118
00119 const ID &
00120 ElasticBeam2d::getExternalNodes(void)
00121 {
00122 return connectedExternalNodes;
00123 }
00124
00125 Node **
00126 ElasticBeam2d::getNodePtrs(void)
00127 {
00128 return theNodes;
00129 }
00130
00131 int
00132 ElasticBeam2d::getNumDOF(void)
00133 {
00134 return 6;
00135 }
00136
00137 void
00138 ElasticBeam2d::setDomain(Domain *theDomain)
00139 {
00140 if (theDomain == 0) {
00141 opserr << "ElasticBeam2d::setDomain -- Domain is null\n";
00142 exit(-1);
00143 }
00144
00145 theNodes[0] = theDomain->getNode(connectedExternalNodes(0));
00146 theNodes[1] = theDomain->getNode(connectedExternalNodes(1));
00147
00148 if (theNodes[0] == 0) {
00149 opserr << "ElasticBeam2d::setDomain -- Node 1: " << connectedExternalNodes(0) << " does not exist\n";
00150 exit(-1);
00151 }
00152
00153 if (theNodes[1] == 0) {
00154 opserr << "ElasticBeam2d::setDomain -- Node 2: " << connectedExternalNodes(1) << " does not exist\n";
00155 exit(-1);
00156 }
00157
00158 int dofNd1 = theNodes[0]->getNumberDOF();
00159 int dofNd2 = theNodes[1]->getNumberDOF();
00160
00161 if (dofNd1 != 3) {
00162 opserr << "ElasticBeam2d::setDomain -- Node 1: " << connectedExternalNodes(0)
00163 << " has incorrect number of DOF\n";
00164 exit(-1);
00165 }
00166
00167 if (dofNd2 != 3) {
00168 opserr << "ElasticBeam2d::setDomain -- Node 2: " << connectedExternalNodes(1)
00169 << " has incorrect number of DOF\n";
00170 exit(-1);
00171 }
00172
00173 this->DomainComponent::setDomain(theDomain);
00174
00175 if (theCoordTransf->initialize(theNodes[0], theNodes[1]) != 0) {
00176 opserr << "ElasticBeam2d::setDomain -- Error initializing coordinate transformation\n";
00177 exit(-1);
00178 }
00179
00180 double L = theCoordTransf->getInitialLength();
00181
00182 if (L == 0.0) {
00183 opserr << "ElasticBeam2d::setDomain -- Element has zero length\n";
00184 exit(-1);
00185 }
00186 }
00187
00188 int
00189 ElasticBeam2d::commitState()
00190 {
00191 int retVal = 0;
00192
00193 if ((retVal = this->Element::commitState()) != 0) {
00194 opserr << "ElasticBeam2d::commitState () - failed in base class";
00195 }
00196 retVal += theCoordTransf->commitState();
00197 return retVal;
00198 }
00199
00200 int
00201 ElasticBeam2d::revertToLastCommit()
00202 {
00203 return theCoordTransf->revertToLastCommit();
00204 }
00205
00206 int
00207 ElasticBeam2d::revertToStart()
00208 {
00209 return theCoordTransf->revertToStart();
00210 }
00211
00212 int
00213 ElasticBeam2d::update(void)
00214 {
00215 return theCoordTransf->update();
00216 }
00217
00218 const Matrix &
00219 ElasticBeam2d::getTangentStiff(void)
00220 {
00221 const Vector &v = theCoordTransf->getBasicTrialDisp();
00222
00223 double L = theCoordTransf->getInitialLength();
00224
00225 double EoverL = E/L;
00226 double EAoverL = A*EoverL;
00227 double EIoverL2 = 2.0*I*EoverL;
00228 double EIoverL4 = 2.0*EIoverL2;
00229
00230
00231 q(0) = EAoverL*v(0);
00232 q(1) = EIoverL4*v(1) + EIoverL2*v(2);
00233 q(2) = EIoverL2*v(1) + EIoverL4*v(2);
00234
00235 q(0) += q0[0];
00236 q(1) += q0[1];
00237 q(2) += q0[2];
00238
00239 kb(0,0) = EAoverL;
00240 kb(1,1) = kb(2,2) = EIoverL4;
00241 kb(2,1) = kb(1,2) = EIoverL2;
00242
00243 return theCoordTransf->getGlobalStiffMatrix(kb, q);
00244 }
00245
00246 const Matrix &
00247 ElasticBeam2d::getInitialStiff(void)
00248 {
00249 double L = theCoordTransf->getInitialLength();
00250
00251 double EoverL = E/L;
00252 double EAoverL = A*EoverL;
00253 double EIoverL2 = 2.0*I*EoverL;
00254 double EIoverL4 = 2.0*EIoverL2;
00255
00256 kb(0,0) = EAoverL;
00257 kb(1,1) = kb(2,2) = EIoverL4;
00258 kb(2,1) = kb(1,2) = EIoverL2;
00259
00260 return theCoordTransf->getInitialGlobalStiffMatrix(kb);
00261 }
00262
00263 const Matrix &
00264 ElasticBeam2d::getMass(void)
00265 {
00266 K.Zero();
00267
00268 if (rho > 0.0) {
00269 double L = theCoordTransf->getInitialLength();
00270 double m = 0.5*rho*L;
00271
00272 K(0,0) = m;
00273 K(1,1) = m;
00274
00275 K(3,3) = m;
00276 K(4,4) = m;
00277 }
00278
00279 return K;
00280 }
00281
00282 void
00283 ElasticBeam2d::zeroLoad(void)
00284 {
00285 Q.Zero();
00286
00287 q0[0] = 0.0;
00288 q0[1] = 0.0;
00289 q0[2] = 0.0;
00290
00291 p0[0] = 0.0;
00292 p0[1] = 0.0;
00293 p0[2] = 0.0;
00294
00295 return;
00296 }
00297
00298 int
00299 ElasticBeam2d::addLoad(ElementalLoad *theLoad, double loadFactor)
00300 {
00301 int type;
00302 const Vector &data = theLoad->getData(type, loadFactor);
00303 double L = theCoordTransf->getInitialLength();
00304
00305 if (type == LOAD_TAG_Beam2dUniformLoad) {
00306 double wt = data(0)*loadFactor;
00307 double wa = data(1)*loadFactor;
00308
00309 double V = 0.5*wt*L;
00310 double M = V*L/6.0;
00311 double P = wa*L;
00312
00313
00314 p0[0] -= P;
00315 p0[1] -= V;
00316 p0[2] -= V;
00317
00318
00319 q0[0] -= 0.5*P;
00320 q0[1] -= M;
00321 q0[2] += M;
00322 }
00323
00324 else if (type == LOAD_TAG_Beam2dPointLoad) {
00325 double P = data(0)*loadFactor;
00326 double N = data(1)*loadFactor;
00327 double aOverL = data(2);
00328
00329 if (aOverL < 0.0 || aOverL > 1.0)
00330 return 0;
00331
00332 double a = aOverL*L;
00333 double b = L-a;
00334
00335
00336 p0[0] -= N;
00337 double V1 = P*(1.0-aOverL);
00338 double V2 = P*aOverL;
00339 p0[1] -= V1;
00340 p0[2] -= V2;
00341
00342 double L2 = 1.0/(L*L);
00343 double a2 = a*a;
00344 double b2 = b*b;
00345
00346
00347 q0[0] -= N*aOverL;
00348 double M1 = -a * b2 * P * L2;
00349 double M2 = a2 * b * P * L2;
00350 q0[1] += M1;
00351 q0[2] += M2;
00352 }
00353
00354 else if (type == LOAD_TAG_Beam2dTempLoad) {
00355 double Ttop1 = data(0)* loadFactor;
00356 double Tbot1 = data(1)* loadFactor;
00357 double Ttop2 = data(2)* loadFactor;
00358 double Tbot2 = data(3)* loadFactor;
00359
00360
00361 double dT1 = Ttop1-Tbot1;
00362 double dT = (Ttop2-Tbot2)-(Ttop1-Tbot1);
00363 double a = alpha/d;
00364
00365 double M1 = a*E*I*(-dT1+(4.0/3.0)*dT);
00366 double M2 = a*E*I*(dT1+(5.0/3.0)*dT);
00367 double F = alpha*(((Ttop2+Ttop1)/2+(Tbot2+Tbot1)/2)/2)*E*A;
00368 double M1M2divL =(M1+M2)/L;
00369
00370
00371 p0[0] += 0;
00372 p0[1] += M1M2divL;
00373 p0[2] -= M1M2divL;
00374
00375
00376 q0[0] -= F;
00377 q0[1] += M1;
00378 q0[2] += M2;
00379 }
00380
00381 else {
00382 opserr << "ElasticBeam2d::addLoad() -- load type unknown for element with tag: " << this->getTag() << endln;
00383 return -1;
00384 }
00385
00386 return 0;
00387 }
00388
00389 int
00390 ElasticBeam2d::addInertiaLoadToUnbalance(const Vector &accel)
00391 {
00392 if (rho == 0.0)
00393 return 0;
00394
00395
00396 const Vector &Raccel1 = theNodes[0]->getRV(accel);
00397 const Vector &Raccel2 = theNodes[1]->getRV(accel);
00398
00399 if (3 != Raccel1.Size() || 3 != Raccel2.Size()) {
00400 opserr << "ElasticBeam2d::addInertiaLoadToUnbalance matrix and vector sizes are incompatable\n";
00401 return -1;
00402 }
00403
00404
00405
00406 double L = theCoordTransf->getInitialLength();
00407 double m = 0.5*rho*L;
00408
00409 Q(0) -= m * Raccel1(0);
00410 Q(1) -= m * Raccel1(1);
00411
00412 Q(3) -= m * Raccel2(0);
00413 Q(4) -= m * Raccel2(1);
00414
00415 return 0;
00416 }
00417
00418 const Vector &
00419 ElasticBeam2d::getResistingForceIncInertia()
00420 {
00421 P = this->getResistingForce();
00422
00423
00424 if (alphaM != 0.0 || betaK != 0.0 || betaK0 != 0.0 || betaKc != 0.0)
00425 P += this->getRayleighDampingForces();
00426
00427 if (rho == 0.0)
00428 return P;
00429
00430 else {
00431 const Vector &accel1 = theNodes[0]->getTrialAccel();
00432 const Vector &accel2 = theNodes[1]->getTrialAccel();
00433
00434 double L = theCoordTransf->getInitialLength();
00435 double m = 0.5*rho*L;
00436
00437 P(0) += m * accel1(0);
00438 P(1) += m * accel1(1);
00439
00440 P(3) += m * accel2(0);
00441 P(4) += m * accel2(1);
00442
00443 return P;
00444 }
00445 }
00446
00447
00448 const Vector &
00449 ElasticBeam2d::getResistingForce()
00450 {
00451 theCoordTransf->update();
00452
00453 const Vector &v = theCoordTransf->getBasicTrialDisp();
00454 double L = theCoordTransf->getInitialLength();
00455
00456 double EoverL = E/L;
00457 double EAoverL = A*EoverL;
00458 double EIoverL2 = 2.0*I*EoverL;
00459 double EIoverL4 = 2.0*EIoverL2;
00460
00461
00462 q(0) = EAoverL*v(0);
00463 q(1) = EIoverL4*v(1) + EIoverL2*v(2);
00464 q(2) = EIoverL2*v(1) + EIoverL4*v(2);
00465
00466 q(0) += q0[0];
00467 q(1) += q0[1];
00468 q(2) += q0[2];
00469
00470
00471 Vector p0Vec(p0, 3);
00472
00473 P = theCoordTransf->getGlobalResistingForce(q, p0Vec);
00474
00475
00476 P.addVector(1.0, Q, -1.0);
00477
00478 return P;
00479 }
00480
00481 int
00482 ElasticBeam2d::sendSelf(int cTag, Channel &theChannel)
00483 {
00484 int res = 0;
00485
00486 static Vector data(11);
00487
00488 data(0) = A;
00489 data(1) = E;
00490 data(2) = I;
00491 data(3) = rho;
00492 data(4) = this->getTag();
00493 data(5) = connectedExternalNodes(0);
00494 data(6) = connectedExternalNodes(1);
00495 data(7) = theCoordTransf->getClassTag();
00496
00497 int dbTag = theCoordTransf->getDbTag();
00498
00499 if (dbTag == 0) {
00500 dbTag = theChannel.getDbTag();
00501 if (dbTag != 0)
00502 theCoordTransf->setDbTag(dbTag);
00503 }
00504
00505 data(8) = dbTag;
00506 data(9) = alpha;
00507 data(10) = d;
00508
00509
00510 res += theChannel.sendVector(this->getDbTag(), cTag, data);
00511 if (res < 0) {
00512 opserr << "ElasticBeam2d::sendSelf -- could not send data Vector\n";
00513 return res;
00514 }
00515
00516
00517 res += theCoordTransf->sendSelf(cTag, theChannel);
00518 if (res < 0) {
00519 opserr << "ElasticBeam2d::sendSelf -- could not send CoordTransf\n";
00520 return res;
00521 }
00522
00523 return res;
00524 }
00525
00526 int
00527 ElasticBeam2d::recvSelf(int cTag, Channel &theChannel, FEM_ObjectBroker &theBroker)
00528 {
00529 int res = 0;
00530
00531 static Vector data(11);
00532
00533 res += theChannel.recvVector(this->getDbTag(), cTag, data);
00534 if (res < 0) {
00535 opserr << "ElasticBeam2d::recvSelf -- could not receive data Vector\n";
00536 return res;
00537 }
00538
00539 A = data(0);
00540 E = data(1);
00541 I = data(2);
00542 alpha = data(9);
00543 d = data(10);
00544
00545 rho = data(3);
00546 this->setTag((int)data(4));
00547 connectedExternalNodes(0) = (int)data(5);
00548 connectedExternalNodes(1) = (int)data(6);
00549
00550
00551 int crdTag = (int)data(7);
00552 if (theCoordTransf == 0) {
00553 theCoordTransf = theBroker.getNewCrdTransf2d(crdTag);
00554 if (theCoordTransf == 0) {
00555 opserr << "ElasticBeam2d::recvSelf -- could not get a CrdTransf2d\n";
00556 exit(-1);
00557 }
00558 }
00559
00560
00561
00562 if (theCoordTransf->getClassTag() != crdTag) {
00563 delete theCoordTransf;
00564 theCoordTransf = theBroker.getNewCrdTransf2d(crdTag);
00565 if (theCoordTransf == 0) {
00566 opserr << "ElasticBeam2d::recvSelf -- could not get a CrdTransf2d\n";
00567 exit(-1);
00568 }
00569 }
00570
00571
00572 theCoordTransf->setDbTag((int)data(8));
00573 res += theCoordTransf->recvSelf(cTag, theChannel, theBroker);
00574 if (res < 0) {
00575 opserr << "ElasticBeam2d::recvSelf -- could not receive CoordTransf\n";
00576 return res;
00577 }
00578
00579
00580 theCoordTransf->revertToLastCommit();
00581
00582 return res;
00583 }
00584
00585 void
00586 ElasticBeam2d::Print(OPS_Stream &s, int flag)
00587 {
00588 if (flag == -1) {
00589 int eleTag = this->getTag();
00590 s << "EL_BEAM\t" << eleTag << "\t";
00591 s << 0 << "\t" << 0 << "\t" << connectedExternalNodes(0) << "\t" << connectedExternalNodes(1) ;
00592 s << "0\t0.0000000\n";
00593 } else {
00594 this->getResistingForce();
00595 s << "\nElasticBeam2d: " << this->getTag() << endln;
00596 s << "\tConnected Nodes: " << connectedExternalNodes ;
00597 s << "\tCoordTransf: " << theCoordTransf->getTag() << endln;
00598 s << "\tmass density: " << rho << endln;
00599 double P = q(0);
00600 double M1 = q(1);
00601 double M2 = q(2);
00602 double L = theCoordTransf->getInitialLength();
00603 double V = (M1+M2)/L;
00604 s << "\tEnd 1 Forces (P V M): " << -P+p0[0]
00605 << " " << V+p0[1] << " " << M1 << endln;
00606 s << "\tEnd 2 Forces (P V M): " << P
00607 << " " << -V+p0[2] << " " << M2 << endln;
00608 }
00609 }
00610
00611 int
00612 ElasticBeam2d::displaySelf(Renderer &theViewer, int displayMode, float fact)
00613 {
00614
00615
00616 const Vector &end1Crd = theNodes[0]->getCrds();
00617 const Vector &end2Crd = theNodes[1]->getCrds();
00618
00619 static Vector v1(3);
00620 static Vector v2(3);
00621
00622 if (displayMode >= 0) {
00623 const Vector &end1Disp = theNodes[0]->getDisp();
00624 const Vector &end2Disp = theNodes[1]->getDisp();
00625
00626 for (int i = 0; i < 2; i++) {
00627 v1(i) = end1Crd(i) + end1Disp(i)*fact;
00628 v2(i) = end2Crd(i) + end2Disp(i)*fact;
00629 }
00630 } else {
00631 int mode = displayMode * -1;
00632 const Matrix &eigen1 = theNodes[0]->getEigenvectors();
00633 const Matrix &eigen2 = theNodes[1]->getEigenvectors();
00634 if (eigen1.noCols() >= mode) {
00635 for (int i = 0; i < 2; i++) {
00636 v1(i) = end1Crd(i) + eigen1(i,mode-1)*fact;
00637 v2(i) = end2Crd(i) + eigen2(i,mode-1)*fact;
00638 }
00639 } else {
00640 for (int i = 0; i < 2; i++) {
00641 v1(i) = end1Crd(i);
00642 v2(i) = end2Crd(i);
00643 }
00644 }
00645 }
00646
00647 return theViewer.drawLine (v1, v2, 1.0, 1.0);
00648 }
00649
00650 Response*
00651 ElasticBeam2d::setResponse(const char **argv, int argc, Information &info, OPS_Stream &output)
00652 {
00653
00654 Response *theResponse = 0;
00655
00656 output.tag("ElementOutput");
00657 output.attr("eleType","ElasticBeam2d");
00658 output.attr("eleTag",this->getTag());
00659 output.attr("node1",connectedExternalNodes[0]);
00660 output.attr("node2",connectedExternalNodes[1]);
00661
00662
00663 if (strcmp(argv[0],"force") == 0 || strcmp(argv[0],"forces") == 0 ||
00664 strcmp(argv[0],"globalForce") == 0 || strcmp(argv[0],"globalForces") == 0) {
00665
00666 output.tag("ResponseType","Px_1");
00667 output.tag("ResponseType","Py_1");
00668 output.tag("ResponseType","Mz_1");
00669 output.tag("ResponseType","Px_2");
00670 output.tag("ResponseType","Py_2");
00671 output.tag("ResponseType","Mz_2");
00672
00673 theResponse = new ElementResponse(this, 2, P);
00674
00675
00676 } else if (strcmp(argv[0],"localForce") == 0 || strcmp(argv[0],"localForces") == 0) {
00677
00678 output.tag("ResponseType","N_1");
00679 output.tag("ResponseType","V_1");
00680 output.tag("ResponseType","M_1");
00681 output.tag("ResponseType","N_2");
00682 output.tag("ResponseType","V_2");
00683 output.tag("ResponseType","M_2");
00684
00685 theResponse = new ElementResponse(this, 3, P);
00686 }
00687
00688 output.endTag();
00689
00690 return theResponse;
00691 }
00692
00693 int
00694 ElasticBeam2d::getResponse (int responseID, Information &eleInfo)
00695 {
00696 double N, M1, M2, V;
00697 double L = theCoordTransf->getInitialLength();
00698
00699 switch (responseID) {
00700 case 1:
00701 return eleInfo.setMatrix(this->getTangentStiff());
00702
00703 case 2:
00704 return eleInfo.setVector(this->getResistingForce());
00705
00706 case 3:
00707
00708 N = q(0);
00709 P(3) = N;
00710 P(0) = -N+p0[0];
00711
00712 M1 = q(1);
00713 M2 = q(2);
00714 P(2) = M1;
00715 P(5) = M2;
00716
00717 V = (M1+M2)/L;
00718 P(1) = V+p0[1];
00719 P(4) = -V+p0[2];
00720 return eleInfo.setVector(P);
00721
00722 default:
00723 return -1;
00724 }
00725 }
00726
00727 int
00728 ElasticBeam2d::setParameter(const char **argv, int argc, Parameter ¶m)
00729 {
00730 if (argc < 1)
00731 return -1;
00732
00733
00734 if (strcmp(argv[0],"E") == 0)
00735 return param.addObject(1, this);
00736
00737
00738 if (strcmp(argv[0],"A") == 0)
00739 return param.addObject(2, this);
00740
00741
00742 if (strcmp(argv[0],"I") == 0)
00743 return param.addObject(3, this);
00744
00745 return -1;
00746 }
00747
00748 int
00749 ElasticBeam2d::updateParameter (int parameterID, Information &info)
00750 {
00751 switch (parameterID) {
00752 case -1:
00753 return -1;
00754 case 1:
00755 E = info.theDouble;
00756 return 0;
00757 case 2:
00758 A = info.theDouble;
00759 return 0;
00760 case 3:
00761 I = info.theDouble;
00762 return 0;
00763 default:
00764 return -1;
00765 }
00766 }
00767