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 #include <DispBeamColumn3d.h>
00031 #include <Node.h>
00032 #include <SectionForceDeformation.h>
00033 #include <CrdTransf3d.h>
00034 #include <Matrix.h>
00035 #include <Vector.h>
00036 #include <ID.h>
00037 #include <Renderer.h>
00038 #include <Domain.h>
00039 #include <string.h>
00040 #include <Information.h>
00041 #include <Channel.h>
00042 #include <FEM_ObjectBroker.h>
00043 #include <ElementResponse.h>
00044 #include <ElementalLoad.h>
00045
00046 Matrix DispBeamColumn3d::K(12,12);
00047 Vector DispBeamColumn3d::P(12);
00048 double DispBeamColumn3d::workArea[200];
00049 GaussQuadRule1d01 DispBeamColumn3d::quadRule;
00050
00051 DispBeamColumn3d::DispBeamColumn3d(int tag, int nd1, int nd2,
00052 int numSec, SectionForceDeformation **s,
00053 CrdTransf3d &coordTransf, double r)
00054 :Element (tag, ELE_TAG_DispBeamColumn3d),
00055 numSections(numSec), theSections(0), crdTransf(0),
00056 connectedExternalNodes(2),
00057 Q(12), q(6), rho(r)
00058 {
00059
00060 theSections = new SectionForceDeformation *[numSections];
00061
00062 if (theSections == 0) {
00063 opserr << "DispBeamColumn3d::DispBeamColumn3d - failed to allocate section model pointer\n";
00064 exit(-1);
00065 }
00066
00067 for (int i = 0; i < numSections; i++) {
00068
00069
00070 theSections[i] = s[i]->getCopy();
00071
00072
00073 if (theSections[i] == 0) {
00074 opserr << "DispBeamColumn3d::DispBeamColumn3d -- failed to get a copy of section model\n";
00075 exit(-1);
00076 }
00077 }
00078
00079 crdTransf = coordTransf.getCopy();
00080
00081 if (crdTransf == 0) {
00082 opserr << "DispBeamColumn3d::DispBeamColumn3d - failed to copy coordinate transformation\n";
00083 exit(-1);
00084 }
00085
00086
00087 connectedExternalNodes(0) = nd1;
00088 connectedExternalNodes(1) = nd2;
00089
00090
00091 theNodes[0] = 0;
00092 theNodes[1] = 0;
00093
00094 q0[0] = 0.0;
00095 q0[1] = 0.0;
00096 q0[2] = 0.0;
00097 q0[3] = 0.0;
00098 q0[4] = 0.0;
00099
00100 p0[0] = 0.0;
00101 p0[1] = 0.0;
00102 p0[2] = 0.0;
00103 p0[3] = 0.0;
00104 p0[4] = 0.0;
00105 }
00106
00107 DispBeamColumn3d::DispBeamColumn3d()
00108 :Element (0, ELE_TAG_DispBeamColumn3d),
00109 numSections(0), theSections(0), crdTransf(0),
00110 connectedExternalNodes(2),
00111 Q(12), q(6), rho(0.0)
00112 {
00113 q0[0] = 0.0;
00114 q0[1] = 0.0;
00115 q0[2] = 0.0;
00116 q0[3] = 0.0;
00117 q0[4] = 0.0;
00118
00119 p0[0] = 0.0;
00120 p0[1] = 0.0;
00121 p0[2] = 0.0;
00122 p0[3] = 0.0;
00123 p0[4] = 0.0;
00124
00125 theNodes[0] = 0;
00126 theNodes[1] = 0;
00127 }
00128
00129 DispBeamColumn3d::~DispBeamColumn3d()
00130 {
00131 for (int i = 0; i < numSections; i++) {
00132 if (theSections[i])
00133 delete theSections[i];
00134 }
00135
00136
00137 if (theSections)
00138 delete [] theSections;
00139
00140 if (crdTransf)
00141 delete crdTransf;
00142 }
00143
00144 int
00145 DispBeamColumn3d::getNumExternalNodes() const
00146 {
00147 return 2;
00148 }
00149
00150 const ID&
00151 DispBeamColumn3d::getExternalNodes()
00152 {
00153 return connectedExternalNodes;
00154 }
00155
00156 Node **
00157 DispBeamColumn3d::getNodePtrs()
00158 {
00159
00160 return theNodes;
00161 }
00162
00163 int
00164 DispBeamColumn3d::getNumDOF()
00165 {
00166 return 12;
00167 }
00168
00169 void
00170 DispBeamColumn3d::setDomain(Domain *theDomain)
00171 {
00172
00173 if (theDomain == 0) {
00174 theNodes[0] = 0;
00175 theNodes[1] = 0;
00176 return;
00177 }
00178
00179 int Nd1 = connectedExternalNodes(0);
00180 int Nd2 = connectedExternalNodes(1);
00181
00182 theNodes[0] = theDomain->getNode(Nd1);
00183 theNodes[1] = theDomain->getNode(Nd2);
00184
00185 if (theNodes[0] == 0 || theNodes[1] == 0) {
00186
00187
00188
00189 return;
00190 }
00191
00192 int dofNd1 = theNodes[0]->getNumberDOF();
00193 int dofNd2 = theNodes[1]->getNumberDOF();
00194
00195 if (dofNd1 != 6 || dofNd2 != 6) {
00196
00197
00198
00199 return;
00200 }
00201
00202 if (crdTransf->initialize(theNodes[0], theNodes[1])) {
00203
00204 }
00205
00206 double L = crdTransf->getInitialLength();
00207
00208 if (L == 0.0) {
00209
00210 }
00211
00212 this->DomainComponent::setDomain(theDomain);
00213
00214 this->update();
00215 }
00216
00217 int
00218 DispBeamColumn3d::commitState()
00219 {
00220 int retVal = 0;
00221
00222
00223 if ((retVal = this->Element::commitState()) != 0) {
00224 opserr << "DispBeamColumn3d::commitState () - failed in base class";
00225 }
00226
00227
00228 for (int i = 0; i < numSections; i++)
00229 retVal += theSections[i]->commitState();
00230
00231 retVal += crdTransf->commitState();
00232
00233 return retVal;
00234 }
00235
00236 int
00237 DispBeamColumn3d::revertToLastCommit()
00238 {
00239 int retVal = 0;
00240
00241
00242 for (int i = 0; i < numSections; i++)
00243 retVal += theSections[i]->revertToLastCommit();
00244
00245 retVal += crdTransf->revertToLastCommit();
00246
00247 return retVal;
00248 }
00249
00250 int
00251 DispBeamColumn3d::revertToStart()
00252 {
00253 int retVal = 0;
00254
00255
00256 for (int i = 0; i < numSections; i++)
00257 retVal += theSections[i]->revertToStart();
00258
00259 retVal += crdTransf->revertToStart();
00260
00261 return retVal;
00262 }
00263
00264 int
00265 DispBeamColumn3d::update(void)
00266 {
00267
00268 crdTransf->update();
00269
00270
00271 const Vector &v = crdTransf->getBasicTrialDisp();
00272
00273 double L = crdTransf->getInitialLength();
00274 double oneOverL = 1.0/L;
00275 const Matrix &pts = quadRule.getIntegrPointCoords(numSections);
00276
00277
00278 for (int i = 0; i < numSections; i++) {
00279
00280 int order = theSections[i]->getOrder();
00281 const ID &code = theSections[i]->getType();
00282
00283 Vector e(workArea, order);
00284
00285 double xi6 = 6.0*pts(i,0);
00286
00287 int j;
00288 for (j = 0; j < order; j++) {
00289 switch(code(j)) {
00290 case SECTION_RESPONSE_P:
00291 e(j) = oneOverL*v(0);
00292 break;
00293 case SECTION_RESPONSE_MZ:
00294 e(j) = oneOverL*((xi6-4.0)*v(1) + (xi6-2.0)*v(2));
00295 break;
00296 case SECTION_RESPONSE_MY:
00297 e(j) = oneOverL*((xi6-4.0)*v(3) + (xi6-2.0)*v(4));
00298 break;
00299 case SECTION_RESPONSE_T:
00300 e(j) = oneOverL*v(5);
00301 break;
00302 default:
00303 e(j) = 0.0;
00304 break;
00305 }
00306 }
00307
00308
00309 theSections[i]->setTrialSectionDeformation(e);
00310 }
00311
00312 return 0;
00313 }
00314
00315 const Matrix&
00316 DispBeamColumn3d::getTangentStiff()
00317 {
00318 static Matrix kb(6,6);
00319
00320
00321 kb.Zero();
00322 q.Zero();
00323
00324 const Matrix &pts = quadRule.getIntegrPointCoords(numSections);
00325 const Vector &wts = quadRule.getIntegrPointWeights(numSections);
00326
00327 double L = crdTransf->getInitialLength();
00328 double oneOverL = 1.0/L;
00329
00330
00331 for (int i = 0; i < numSections; i++) {
00332
00333 int order = theSections[i]->getOrder();
00334 const ID &code = theSections[i]->getType();
00335
00336 Matrix ka(workArea, order, 6);
00337 ka.Zero();
00338
00339 double xi6 = 6.0*pts(i,0);
00340
00341
00342 const Matrix &ks = theSections[i]->getSectionTangent();
00343 const Vector &s = theSections[i]->getStressResultant();
00344
00345
00346
00347 double wti = wts(i)*oneOverL;
00348 double tmp;
00349 int j, k;
00350 for (j = 0; j < order; j++) {
00351 switch(code(j)) {
00352 case SECTION_RESPONSE_P:
00353 for (k = 0; k < order; k++)
00354 ka(k,0) += ks(k,j)*wti;
00355 break;
00356 case SECTION_RESPONSE_MZ:
00357 for (k = 0; k < order; k++) {
00358 tmp = ks(k,j)*wti;
00359 ka(k,1) += (xi6-4.0)*tmp;
00360 ka(k,2) += (xi6-2.0)*tmp;
00361 }
00362 break;
00363 case SECTION_RESPONSE_MY:
00364 for (k = 0; k < order; k++) {
00365 tmp = ks(k,j)*wti;
00366 ka(k,3) += (xi6-4.0)*tmp;
00367 ka(k,4) += (xi6-2.0)*tmp;
00368 }
00369 break;
00370 case SECTION_RESPONSE_T:
00371 for (k = 0; k < order; k++)
00372 ka(k,5) += ks(k,j)*wti;
00373 break;
00374 default:
00375 break;
00376 }
00377 }
00378 for (j = 0; j < order; j++) {
00379 switch (code(j)) {
00380 case SECTION_RESPONSE_P:
00381 for (k = 0; k < 6; k++)
00382 kb(0,k) += ka(j,k);
00383 break;
00384 case SECTION_RESPONSE_MZ:
00385 for (k = 0; k < 6; k++) {
00386 tmp = ka(j,k);
00387 kb(1,k) += (xi6-4.0)*tmp;
00388 kb(2,k) += (xi6-2.0)*tmp;
00389 }
00390 break;
00391 case SECTION_RESPONSE_MY:
00392 for (k = 0; k < 6; k++) {
00393 tmp = ka(j,k);
00394 kb(3,k) += (xi6-4.0)*tmp;
00395 kb(4,k) += (xi6-2.0)*tmp;
00396 }
00397 break;
00398 case SECTION_RESPONSE_T:
00399 for (k = 0; k < 6; k++)
00400 kb(5,k) += ka(j,k);
00401 break;
00402 default:
00403 break;
00404 }
00405 }
00406
00407
00408 double si;
00409 for (j = 0; j < order; j++) {
00410 si = s(j)*wts(i);
00411 switch(code(j)) {
00412 case SECTION_RESPONSE_P:
00413 q(0) += si;
00414 break;
00415 case SECTION_RESPONSE_MZ:
00416 q(1) += (xi6-4.0)*si; q(2) += (xi6-2.0)*si;
00417 break;
00418 case SECTION_RESPONSE_MY:
00419 q(3) += (xi6-4.0)*si; q(4) += (xi6-2.0)*si;
00420 break;
00421 case SECTION_RESPONSE_T:
00422 q(5) += si;
00423 break;
00424 default:
00425 break;
00426 }
00427 }
00428
00429 }
00430
00431 q(0) += q0[0];
00432 q(1) += q0[1];
00433 q(2) += q0[2];
00434 q(3) += q0[3];
00435 q(4) += q0[4];
00436
00437
00438 K = crdTransf->getGlobalStiffMatrix(kb, q);
00439
00440 return K;
00441 }
00442
00443 const Matrix&
00444 DispBeamColumn3d::getInitialBasicStiff()
00445 {
00446 static Matrix kb(6,6);
00447
00448
00449 kb.Zero();
00450
00451 const Matrix &pts = quadRule.getIntegrPointCoords(numSections);
00452 const Vector &wts = quadRule.getIntegrPointWeights(numSections);
00453
00454 double L = crdTransf->getInitialLength();
00455 double oneOverL = 1.0/L;
00456
00457
00458 for (int i = 0; i < numSections; i++) {
00459
00460 int order = theSections[i]->getOrder();
00461 const ID &code = theSections[i]->getType();
00462
00463 Matrix ka(workArea, order, 6);
00464 ka.Zero();
00465
00466 double xi6 = 6.0*pts(i,0);
00467
00468
00469 const Matrix &ks = theSections[i]->getInitialTangent();
00470
00471
00472
00473 double wti = wts(i)*oneOverL;
00474 double tmp;
00475 int j, k;
00476 for (j = 0; j < order; j++) {
00477 switch(code(j)) {
00478 case SECTION_RESPONSE_P:
00479 for (k = 0; k < order; k++)
00480 ka(k,0) += ks(k,j)*wti;
00481 break;
00482 case SECTION_RESPONSE_MZ:
00483 for (k = 0; k < order; k++) {
00484 tmp = ks(k,j)*wti;
00485 ka(k,1) += (xi6-4.0)*tmp;
00486 ka(k,2) += (xi6-2.0)*tmp;
00487 }
00488 break;
00489 case SECTION_RESPONSE_MY:
00490 for (k = 0; k < order; k++) {
00491 tmp = ks(k,j)*wti;
00492 ka(k,3) += (xi6-4.0)*tmp;
00493 ka(k,4) += (xi6-2.0)*tmp;
00494 }
00495 break;
00496 case SECTION_RESPONSE_T:
00497 for (k = 0; k < order; k++)
00498 ka(k,5) += ks(k,j)*wti;
00499 break;
00500 default:
00501 break;
00502 }
00503 }
00504 for (j = 0; j < order; j++) {
00505 switch (code(j)) {
00506 case SECTION_RESPONSE_P:
00507 for (k = 0; k < 6; k++)
00508 kb(0,k) += ka(j,k);
00509 break;
00510 case SECTION_RESPONSE_MZ:
00511 for (k = 0; k < 6; k++) {
00512 tmp = ka(j,k);
00513 kb(1,k) += (xi6-4.0)*tmp;
00514 kb(2,k) += (xi6-2.0)*tmp;
00515 }
00516 break;
00517 case SECTION_RESPONSE_MY:
00518 for (k = 0; k < 6; k++) {
00519 tmp = ka(j,k);
00520 kb(3,k) += (xi6-4.0)*tmp;
00521 kb(4,k) += (xi6-2.0)*tmp;
00522 }
00523 break;
00524 case SECTION_RESPONSE_T:
00525 for (k = 0; k < 6; k++)
00526 kb(5,k) += ka(j,k);
00527 break;
00528 default:
00529 break;
00530 }
00531 }
00532
00533 }
00534
00535 return kb;
00536 }
00537
00538 const Matrix&
00539 DispBeamColumn3d::getInitialStiff()
00540 {
00541 const Matrix &kb = this->getInitialBasicStiff();
00542
00543
00544 K = crdTransf->getInitialGlobalStiffMatrix(kb);
00545
00546 return K;
00547 }
00548
00549 const Matrix&
00550 DispBeamColumn3d::getMass()
00551 {
00552 K.Zero();
00553
00554 if (rho == 0.0)
00555 return K;
00556
00557 double L = crdTransf->getInitialLength();
00558 double m = 0.5*rho*L;
00559
00560 K(0,0) = K(1,1) = K(2,2) = K(6,6) = K(7,7) = K(8,8) = m;
00561
00562 return K;
00563 }
00564
00565 void
00566 DispBeamColumn3d::zeroLoad(void)
00567 {
00568 Q.Zero();
00569
00570 q0[0] = 0.0;
00571 q0[1] = 0.0;
00572 q0[2] = 0.0;
00573 q0[3] = 0.0;
00574 q0[4] = 0.0;
00575
00576 p0[0] = 0.0;
00577 p0[1] = 0.0;
00578 p0[2] = 0.0;
00579 p0[3] = 0.0;
00580 p0[4] = 0.0;
00581
00582 return;
00583 }
00584
00585 int
00586 DispBeamColumn3d::addLoad(ElementalLoad *theLoad, double loadFactor)
00587 {
00588 int type;
00589 const Vector &data = theLoad->getData(type, loadFactor);
00590 double L = crdTransf->getInitialLength();
00591
00592 if (type == LOAD_TAG_Beam3dUniformLoad) {
00593 double wy = data(0)*loadFactor;
00594 double wz = data(1)*loadFactor;
00595 double wx = data(2)*loadFactor;
00596
00597 double Vy = 0.5*wy*L;
00598 double Mz = Vy*L/6.0;
00599 double Vz = 0.5*wz*L;
00600 double My = Vz*L/6.0;
00601 double P = wx*L;
00602
00603
00604 p0[0] -= P;
00605 p0[1] -= Vy;
00606 p0[2] -= Vy;
00607 p0[3] -= Vz;
00608 p0[4] -= Vz;
00609
00610
00611 q0[0] -= 0.5*P;
00612 q0[1] -= Mz;
00613 q0[2] += Mz;
00614 q0[3] += My;
00615 q0[4] -= My;
00616 }
00617 else if (type == LOAD_TAG_Beam3dPointLoad) {
00618 double Py = data(0)*loadFactor;
00619 double Pz = data(1)*loadFactor;
00620 double N = data(2)*loadFactor;
00621 double aOverL = data(3);
00622
00623 if (aOverL < 0.0 || aOverL > 1.0)
00624 return 0;
00625
00626 double a = aOverL*L;
00627 double b = L-a;
00628
00629
00630 p0[0] -= N;
00631 double V1, V2;
00632 V1 = Py*(1.0-aOverL);
00633 V2 = Py*aOverL;
00634 p0[1] -= V1;
00635 p0[2] -= V2;
00636 V1 = Pz*(1.0-aOverL);
00637 V2 = Pz*aOverL;
00638 p0[3] -= V1;
00639 p0[4] -= V2;
00640
00641 double L2 = 1.0/(L*L);
00642 double a2 = a*a;
00643 double b2 = b*b;
00644
00645
00646 q0[0] -= N*aOverL;
00647 double M1, M2;
00648 M1 = -a * b2 * Py * L2;
00649 M2 = a2 * b * Py * L2;
00650 q0[1] += M1;
00651 q0[2] += M2;
00652 M1 = -a * b2 * Pz * L2;
00653 M2 = a2 * b * Pz * L2;
00654 q0[3] -= M1;
00655 q0[4] -= M2;
00656 }
00657 else {
00658 opserr << "DispBeamColumn2d::addLoad() -- load type unknown for element with tag: " <<
00659 this->getTag() << endln;
00660 return -1;
00661 }
00662
00663 return 0;
00664 }
00665
00666 int
00667 DispBeamColumn3d::addInertiaLoadToUnbalance(const Vector &accel)
00668 {
00669
00670 if (rho == 0.0)
00671 return 0;
00672
00673
00674 const Vector &Raccel1 = theNodes[0]->getRV(accel);
00675 const Vector &Raccel2 = theNodes[1]->getRV(accel);
00676
00677 if (6 != Raccel1.Size() || 6 != Raccel2.Size()) {
00678 opserr << "DispBeamColumn3d::addInertiaLoadToUnbalance matrix and vector sizes are incompatable\n";
00679 return -1;
00680 }
00681
00682 double L = crdTransf->getInitialLength();
00683 double m = 0.5*rho*L;
00684
00685
00686
00687 Q(0) -= m*Raccel1(0);
00688 Q(1) -= m*Raccel1(1);
00689 Q(2) -= m*Raccel1(2);
00690 Q(6) -= m*Raccel2(0);
00691 Q(7) -= m*Raccel2(1);
00692 Q(8) -= m*Raccel2(2);
00693
00694 return 0;
00695 }
00696
00697 const Vector&
00698 DispBeamColumn3d::getResistingForce()
00699 {
00700 const Matrix &pts = quadRule.getIntegrPointCoords(numSections);
00701 const Vector &wts = quadRule.getIntegrPointWeights(numSections);
00702
00703
00704 q.Zero();
00705
00706
00707 for (int i = 0; i < numSections; i++) {
00708
00709 int order = theSections[i]->getOrder();
00710 const ID &code = theSections[i]->getType();
00711
00712 double xi6 = 6.0*pts(i,0);
00713
00714
00715 const Vector &s = theSections[i]->getStressResultant();
00716
00717
00718
00719
00720 double si;
00721 for (int j = 0; j < order; j++) {
00722 si = s(j)*wts(i);
00723 switch(code(j)) {
00724 case SECTION_RESPONSE_P:
00725 q(0) += si;
00726 break;
00727 case SECTION_RESPONSE_MZ:
00728 q(1) += (xi6-4.0)*si; q(2) += (xi6-2.0)*si;
00729 break;
00730 case SECTION_RESPONSE_MY:
00731 q(3) += (xi6-4.0)*si; q(4) += (xi6-2.0)*si;
00732 break;
00733 case SECTION_RESPONSE_T:
00734 q(5) += si;
00735 break;
00736 default:
00737 break;
00738 }
00739 }
00740
00741 }
00742
00743 q(0) += q0[0];
00744 q(1) += q0[1];
00745 q(2) += q0[2];
00746 q(3) += q0[3];
00747 q(4) += q0[4];
00748
00749
00750 Vector p0Vec(p0, 5);
00751 P = crdTransf->getGlobalResistingForce(q, p0Vec);
00752
00753
00754 P.addVector(1.0, Q, -1.0);
00755
00756 return P;
00757 }
00758
00759 const Vector&
00760 DispBeamColumn3d::getResistingForceIncInertia()
00761 {
00762 this->getResistingForce();
00763
00764 if (rho != 0.0) {
00765 const Vector &accel1 = theNodes[0]->getTrialAccel();
00766 const Vector &accel2 = theNodes[1]->getTrialAccel();
00767
00768
00769 this->getResistingForce();
00770
00771 double L = crdTransf->getInitialLength();
00772 double m = 0.5*rho*L;
00773
00774 P(0) += m*accel1(0);
00775 P(1) += m*accel1(1);
00776 P(2) += m*accel1(2);
00777 P(6) += m*accel2(0);
00778 P(7) += m*accel2(1);
00779 P(8) += m*accel2(2);
00780
00781
00782 if (alphaM != 0.0 || betaK != 0.0 || betaK0 != 0.0 || betaKc != 0.0)
00783 P += this->getRayleighDampingForces();
00784
00785 } else {
00786
00787
00788 if (betaK != 0.0 || betaK0 != 0.0 || betaKc != 0.0)
00789 P += this->getRayleighDampingForces();
00790 }
00791
00792 return P;
00793 }
00794
00795 int
00796 DispBeamColumn3d::sendSelf(int commitTag, Channel &theChannel)
00797 {
00798
00799
00800 int dbTag = this->getDbTag();
00801 int i, j;
00802 int loc = 0;
00803
00804 static ID idData(7);
00805 idData(0) = this->getTag();
00806 idData(1) = connectedExternalNodes(0);
00807 idData(2) = connectedExternalNodes(1);
00808 idData(3) = numSections;
00809 idData(4) = crdTransf->getClassTag();
00810 int crdTransfDbTag = crdTransf->getDbTag();
00811 if (crdTransfDbTag == 0) {
00812 crdTransfDbTag = theChannel.getDbTag();
00813 if (crdTransfDbTag != 0)
00814 crdTransf->setDbTag(crdTransfDbTag);
00815 }
00816 idData(5) = crdTransfDbTag;
00817
00818 if (theChannel.sendID(dbTag, commitTag, idData) < 0) {
00819 opserr << "DispBeamColumn3d::sendSelf() - failed to send ID data\n";
00820 return -1;
00821 }
00822
00823
00824
00825 if (crdTransf->sendSelf(commitTag, theChannel) < 0) {
00826 opserr << "DispBeamColumn3d::sendSelf() - failed to send crdTranf\n";
00827 return -1;
00828 }
00829
00830
00831
00832
00833
00834
00835
00836 ID idSections(2*numSections);
00837 loc = 0;
00838 for (i = 0; i<numSections; i++) {
00839 int sectClassTag = theSections[i]->getClassTag();
00840 int sectDbTag = theSections[i]->getDbTag();
00841 if (sectDbTag == 0) {
00842 sectDbTag = theChannel.getDbTag();
00843 theSections[i]->setDbTag(sectDbTag);
00844 }
00845
00846 idSections(loc) = sectClassTag;
00847 idSections(loc+1) = sectDbTag;
00848 loc += 2;
00849 }
00850
00851 if (theChannel.sendID(dbTag, commitTag, idSections) < 0) {
00852 opserr << "DispBeamColumn3d::sendSelf() - failed to send ID data\n";
00853 return -1;
00854 }
00855
00856
00857
00858
00859
00860 for (j = 0; j<numSections; j++) {
00861 if (theSections[j]->sendSelf(commitTag, theChannel) < 0) {
00862 opserr << "DispBeamColumn3d::sendSelf() - section " << j << "failed to send itself\n";
00863 return -1;
00864 }
00865 }
00866
00867 return 0;
00868 }
00869
00870 int
00871 DispBeamColumn3d::recvSelf(int commitTag, Channel &theChannel,
00872 FEM_ObjectBroker &theBroker)
00873 {
00874
00875
00876
00877 int dbTag = this->getDbTag();
00878 int i;
00879
00880 static ID idData(7);
00881
00882 if (theChannel.recvID(dbTag, commitTag, idData) < 0) {
00883 opserr << "DispBeamColumn3d::recvSelf() - failed to recv ID data\n";
00884 return -1;
00885 }
00886
00887 this->setTag(idData(0));
00888 connectedExternalNodes(0) = idData(1);
00889 connectedExternalNodes(1) = idData(2);
00890
00891 int crdTransfClassTag = idData(4);
00892 int crdTransfDbTag = idData(5);
00893
00894
00895 if (crdTransf == 0 || crdTransf->getClassTag() != crdTransfClassTag) {
00896 if (crdTransf != 0)
00897 delete crdTransf;
00898
00899 crdTransf = theBroker.getNewCrdTransf3d(crdTransfClassTag);
00900
00901 if (crdTransf == 0) {
00902 opserr << "DispBeamColumn3d::recvSelf() - " <<
00903 "failed to obtain a CrdTrans object with classTag" <<
00904 crdTransfClassTag << endln;
00905 return -2;
00906 }
00907 }
00908
00909 crdTransf->setDbTag(crdTransfDbTag);
00910
00911
00912 if (crdTransf->recvSelf(commitTag, theChannel, theBroker) < 0) {
00913 opserr << "DispBeamColumn3d::sendSelf() - failed to recv crdTranf\n";
00914 return -3;
00915 }
00916
00917
00918
00919
00920
00921 ID idSections(2*idData(3));
00922 int loc = 0;
00923
00924 if (theChannel.recvID(dbTag, commitTag, idSections) < 0) {
00925 opserr << "DispBeamColumn3d::recvSelf() - failed to recv ID data\n";
00926 return -1;
00927 }
00928
00929
00930
00931
00932
00933 if (numSections != idData(3)) {
00934
00935
00936
00937
00938
00939
00940
00941 if (numSections != 0) {
00942 for (int i=0; i<numSections; i++)
00943 delete theSections[i];
00944 delete [] theSections;
00945 }
00946
00947
00948 theSections = new SectionForceDeformation *[idData(3)];
00949 if (theSections == 0) {
00950 opserr << "DispBeamColumn3d::recvSelf() - out of memory creating sections array of size" <<
00951 idData(3) << endln;
00952 exit(-1);
00953 }
00954
00955
00956 numSections = idData(3);
00957 loc = 0;
00958
00959 for (i=0; i<numSections; i++) {
00960 int sectClassTag = idSections(loc);
00961 int sectDbTag = idSections(loc+1);
00962 loc += 2;
00963 theSections[i] = theBroker.getNewSection(sectClassTag);
00964 if (theSections[i] == 0) {
00965 opserr << "DispBeamColumn3d::recvSelf() - Broker could not create Section of class type" <<
00966 sectClassTag << endln;
00967 exit(-1);
00968 }
00969 theSections[i]->setDbTag(sectDbTag);
00970 if (theSections[i]->recvSelf(commitTag, theChannel, theBroker) < 0) {
00971 opserr << "DispBeamColumn3d::recvSelf() - section " <<
00972 i << "failed to recv itself\n";
00973 return -1;
00974 }
00975 }
00976
00977 } else {
00978
00979
00980
00981
00982
00983
00984 loc = 0;
00985 for (i=0; i<numSections; i++) {
00986 int sectClassTag = idSections(loc);
00987 int sectDbTag = idSections(loc+1);
00988 loc += 2;
00989
00990
00991 if (theSections[i]->getClassTag() != sectClassTag) {
00992
00993 delete theSections[i];
00994 theSections[i] = theBroker.getNewSection(sectClassTag);
00995 if (theSections[i] == 0) {
00996 opserr << "DispBeamColumn3d::recvSelf() - Broker could not create Section of class type" <<
00997 sectClassTag << endln;
00998 exit(-1);
00999 }
01000 }
01001
01002
01003 theSections[i]->setDbTag(sectDbTag);
01004 if (theSections[i]->recvSelf(commitTag, theChannel, theBroker) < 0) {
01005 opserr << "DispBeamColumn3d::recvSelf() - section " <<
01006 i << "failed to recv itself\n";
01007 return -1;
01008 }
01009 }
01010 }
01011
01012 return 0;
01013 }
01014
01015 void
01016 DispBeamColumn3d::Print(OPS_Stream &s, int flag)
01017 {
01018 s << "\nDispBeamColumn3d, element id: " << this->getTag() << endln;
01019 s << "\tConnected external nodes: " << connectedExternalNodes;
01020 s << "\tmass density: " << rho << endln;
01021
01022 double N, Mz1, Mz2, Vy, My1, My2, Vz, T;
01023 double L = crdTransf->getInitialLength();
01024 double oneOverL = 1.0/L;
01025
01026 N = q(0);
01027 Mz1 = q(1);
01028 Mz2 = q(2);
01029 Vy = (Mz1+Mz2)*oneOverL;
01030 My1 = q(3);
01031 My2 = q(4);
01032 Vz = -(My1+My2)*oneOverL;
01033 T = q(5);
01034
01035 s << "\tEnd 1 Forces (P Mz Vy My Vz T): "
01036 << -N+p0[0] << ' ' << Mz1 << ' ' << Vy+p0[1] << ' ' << My1 << ' ' << Vz+p0[3] << ' ' << -T << endln;
01037 s << "\tEnd 2 Forces (P Mz Vy My Vz T): "
01038 << N << ' ' << Mz2 << ' ' << -Vy+p0[2] << ' ' << My2 << ' ' << -Vz+p0[4] << ' ' << T << endln;
01039
01040
01041
01042 }
01043
01044
01045 int
01046 DispBeamColumn3d::displaySelf(Renderer &theViewer, int displayMode, float fact)
01047 {
01048
01049
01050 const Vector &end1Crd = theNodes[0]->getCrds();
01051 const Vector &end2Crd = theNodes[1]->getCrds();
01052
01053 static Vector v1(3);
01054 static Vector v2(3);
01055
01056 if (displayMode >= 0) {
01057 const Vector &end1Disp = theNodes[0]->getDisp();
01058 const Vector &end2Disp = theNodes[1]->getDisp();
01059
01060 for (int i = 0; i < 3; i++) {
01061 v1(i) = end1Crd(i) + end1Disp(i)*fact;
01062 v2(i) = end2Crd(i) + end2Disp(i)*fact;
01063 }
01064 } else {
01065 int mode = displayMode * -1;
01066 const Matrix &eigen1 = theNodes[0]->getEigenvectors();
01067 const Matrix &eigen2 = theNodes[1]->getEigenvectors();
01068 if (eigen1.noCols() >= mode) {
01069 for (int i = 0; i < 3; i++) {
01070 v1(i) = end1Crd(i) + eigen1(i,mode-1)*fact;
01071 v2(i) = end2Crd(i) + eigen2(i,mode-1)*fact;
01072 }
01073
01074 } else {
01075 for (int i = 0; i < 3; i++) {
01076 v1(i) = end1Crd(i);
01077 v2(i) = end2Crd(i);
01078 }
01079 }
01080 }
01081 return theViewer.drawLine (v1, v2, 1.0, 1.0);
01082 }
01083
01084 Response*
01085 DispBeamColumn3d::setResponse(const char **argv, int argc, Information &eleInfo, OPS_Stream &output)
01086 {
01087
01088 Response *theResponse = 0;
01089
01090 output.tag("ElementOutput");
01091 output.attr("eleType","DispBeamColumn2d");
01092 output.attr("eleTag",this->getTag());
01093 output.attr("node1",connectedExternalNodes[0]);
01094 output.attr("node2",connectedExternalNodes[1]);
01095
01096
01097
01098
01099
01100
01101 if (strcmp(argv[0],"forces") == 0 || strcmp(argv[0],"force") == 0
01102 || strcmp(argv[0],"globalForce") == 0 || strcmp(argv[0],"globalForces") == 0) {
01103
01104 output.tag("ResponseType","Px_1");
01105 output.tag("ResponseType","Py_1");
01106 output.tag("ResponseType","Pz_1");
01107 output.tag("ResponseType","Mx_1");
01108 output.tag("ResponseType","My_1");
01109 output.tag("ResponseType","Mz_1");
01110 output.tag("ResponseType","Px_2");
01111 output.tag("ResponseType","Py_2");
01112 output.tag("ResponseType","Pz_2");
01113 output.tag("ResponseType","Mx_2");
01114 output.tag("ResponseType","My_2");
01115 output.tag("ResponseType","Mz_2");
01116
01117
01118 theResponse = new ElementResponse(this, 1, P);
01119
01120
01121 } else if (strcmp(argv[0],"localForce") == 0 || strcmp(argv[0],"localForces") == 0) {
01122
01123 output.tag("ResponseType","N_ 1");
01124 output.tag("ResponseType","Vy_1");
01125 output.tag("ResponseType","Vz_1");
01126 output.tag("ResponseType","T_1");
01127 output.tag("ResponseType","My_1");
01128 output.tag("ResponseType","Tz_1");
01129 output.tag("ResponseType","N_2");
01130 output.tag("ResponseType","Py_2");
01131 output.tag("ResponseType","Pz_2");
01132 output.tag("ResponseType","T_2");
01133 output.tag("ResponseType","My_2");
01134 output.tag("ResponseType","Mz_2");
01135
01136 theResponse = new ElementResponse(this, 2, P);
01137
01138
01139 } else if (strcmp(argv[0],"chordRotation") == 0 || strcmp(argv[0],"chordDeformation") == 0
01140 || strcmp(argv[0],"basicDeformation") == 0) {
01141
01142 output.tag("ResponseType","eps");
01143 output.tag("ResponseType","thetaZ_1");
01144 output.tag("ResponseType","thetaZ_2");
01145 output.tag("ResponseType","thetaY_1");
01146 output.tag("ResponseType","thetaY_2");
01147 output.tag("ResponseType","thetaX");
01148
01149 theResponse = new ElementResponse(this, 3, Vector(6));
01150
01151
01152 } else if (strcmp(argv[0],"plasticRotation") == 0 || strcmp(argv[0],"plasticDeformation") == 0) {
01153
01154 output.tag("ResponseType","epsP");
01155 output.tag("ResponseType","thetaZP_1");
01156 output.tag("ResponseType","thetaZP_2");
01157 output.tag("ResponseType","thetaYP_1");
01158 output.tag("ResponseType","thetaYP_2");
01159 output.tag("ResponseType","thetaXP");
01160
01161 theResponse = new ElementResponse(this, 4, Vector(6));
01162
01163
01164 } else if (strcmp(argv[0],"section") ==0) {
01165 if (argc > 2) {
01166
01167 int sectionNum = atoi(argv[1]);
01168 if (sectionNum > 0 && sectionNum <= numSections) {
01169
01170 output.tag("GaussPointOutput");
01171 output.attr("number",sectionNum);
01172 const Matrix &pts = quadRule.getIntegrPointCoords(numSections);
01173 output.attr("eta",2.0*pts(sectionNum-1,0)-1);
01174
01175 theResponse = theSections[sectionNum-1]->setResponse(&argv[2], argc-2, eleInfo, output);
01176
01177 output.endTag();
01178 }
01179 }
01180 }
01181
01182 output.endTag();
01183 return theResponse;
01184 }
01185
01186 int
01187 DispBeamColumn3d::getResponse(int responseID, Information &eleInfo)
01188 {
01189 double N, V, M1, M2, T;
01190 double L = crdTransf->getInitialLength();
01191 double oneOverL = 1.0/L;
01192
01193 if (responseID == 1)
01194 return eleInfo.setVector(this->getResistingForce());
01195
01196 else if (responseID == 2) {
01197
01198 N = q(0);
01199 P(6) = N;
01200 P(0) = -N+p0[0];
01201
01202
01203 T = q(5);
01204 P(9) = T;
01205 P(3) = -T;
01206
01207
01208 M1 = q(1);
01209 M2 = q(2);
01210 P(5) = M1;
01211 P(11) = M2;
01212 V = (M1+M2)*oneOverL;
01213 P(1) = V+p0[1];
01214 P(7) = -V+p0[2];
01215
01216
01217 M1 = q(3);
01218 M2 = q(4);
01219 P(4) = M1;
01220 P(10) = M2;
01221 V = -(M1+M2)*oneOverL;
01222 P(2) = -V+p0[3];
01223 P(8) = V+p0[4];
01224
01225 return eleInfo.setVector(P);
01226 }
01227
01228
01229 else if (responseID == 3)
01230 return eleInfo.setVector(crdTransf->getBasicTrialDisp());
01231
01232
01233 else if (responseID == 4) {
01234 static Vector vp(6);
01235 static Vector ve(6);
01236 const Matrix &kb = this->getInitialBasicStiff();
01237 kb.Solve(q, ve);
01238 vp = crdTransf->getBasicTrialDisp();
01239 vp -= ve;
01240 return eleInfo.setVector(vp);
01241 }
01242
01243 else
01244 return -1;
01245 }