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 <DispBeamColumn2d.h>
00031 #include <Node.h>
00032 #include <SectionForceDeformation.h>
00033 #include <CrdTransf2d.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 <Parameter.h>
00042 #include <Channel.h>
00043 #include <FEM_ObjectBroker.h>
00044 #include <ElementResponse.h>
00045 #include <ElementalLoad.h>
00046
00047 Matrix DispBeamColumn2d::K(6,6);
00048 Vector DispBeamColumn2d::P(6);
00049 double DispBeamColumn2d::workArea[100];
00050
00051 DispBeamColumn2d::DispBeamColumn2d(int tag, int nd1, int nd2,
00052 int numSec, SectionForceDeformation **s,
00053 BeamIntegration& bi,
00054 CrdTransf2d &coordTransf, double r)
00055 :Element (tag, ELE_TAG_DispBeamColumn2d),
00056 numSections(numSec), theSections(0), crdTransf(0), beamInt(0),
00057 connectedExternalNodes(2),
00058 Q(6), q(3), rho(r)
00059 {
00060
00061 theSections = new SectionForceDeformation *[numSections];
00062
00063 if (theSections == 0) {
00064 opserr << "DispBeamColumn2d::DispBeamColumn2d - failed to allocate section model pointer\n";
00065 exit(-1);
00066 }
00067
00068 for (int i = 0; i < numSections; i++) {
00069
00070
00071 theSections[i] = s[i]->getCopy();
00072
00073
00074 if (theSections[i] == 0) {
00075 opserr << "DispBeamColumn2d::DispBeamColumn2d -- failed to get a copy of section model\n";
00076 exit(-1);
00077 }
00078 }
00079
00080 beamInt = bi.getCopy();
00081
00082 if (beamInt == 0) {
00083 opserr << "DispBeamColumn2d::DispBeamColumn2d - failed to copy beam integration\n";
00084 exit(-1);
00085 }
00086
00087 crdTransf = coordTransf.getCopy();
00088
00089 if (crdTransf == 0) {
00090 opserr << "DispBeamColumn2d::DispBeamColumn2d - failed to copy coordinate transformation\n";
00091 exit(-1);
00092 }
00093
00094
00095 connectedExternalNodes(0) = nd1;
00096 connectedExternalNodes(1) = nd2;
00097
00098 theNodes[0] = 0;
00099 theNodes[1] = 0;
00100
00101 q0[0] = 0.0;
00102 q0[1] = 0.0;
00103 q0[2] = 0.0;
00104
00105 p0[0] = 0.0;
00106 p0[1] = 0.0;
00107 p0[2] = 0.0;
00108
00109
00110 parameterID = 0;
00111
00112 }
00113
00114 DispBeamColumn2d::DispBeamColumn2d()
00115 :Element (0, ELE_TAG_DispBeamColumn2d),
00116 numSections(0), theSections(0), crdTransf(0), beamInt(0),
00117 connectedExternalNodes(2),
00118 Q(6), q(3), rho(0.0)
00119 {
00120 q0[0] = 0.0;
00121 q0[1] = 0.0;
00122 q0[2] = 0.0;
00123
00124 p0[0] = 0.0;
00125 p0[1] = 0.0;
00126 p0[2] = 0.0;
00127
00128 theNodes[0] = 0;
00129 theNodes[1] = 0;
00130
00131
00132 parameterID = 0;
00133
00134 }
00135
00136 DispBeamColumn2d::~DispBeamColumn2d()
00137 {
00138 for (int i = 0; i < numSections; i++) {
00139 if (theSections[i])
00140 delete theSections[i];
00141 }
00142
00143
00144 if (theSections)
00145 delete [] theSections;
00146
00147 if (crdTransf)
00148 delete crdTransf;
00149
00150 if (beamInt != 0)
00151 delete beamInt;
00152 }
00153
00154 int
00155 DispBeamColumn2d::getNumExternalNodes() const
00156 {
00157 return 2;
00158 }
00159
00160 const ID&
00161 DispBeamColumn2d::getExternalNodes()
00162 {
00163 return connectedExternalNodes;
00164 }
00165
00166 Node **
00167 DispBeamColumn2d::getNodePtrs()
00168 {
00169 return theNodes;
00170 }
00171
00172 int
00173 DispBeamColumn2d::getNumDOF()
00174 {
00175 return 6;
00176 }
00177
00178 void
00179 DispBeamColumn2d::setDomain(Domain *theDomain)
00180 {
00181
00182 if (theDomain == 0) {
00183 theNodes[0] = 0;
00184 theNodes[1] = 0;
00185 return;
00186 }
00187
00188 int Nd1 = connectedExternalNodes(0);
00189 int Nd2 = connectedExternalNodes(1);
00190
00191 theNodes[0] = theDomain->getNode(Nd1);
00192 theNodes[1] = theDomain->getNode(Nd2);
00193
00194 if (theNodes[0] == 0 || theNodes[1] == 0) {
00195
00196
00197
00198 return;
00199 }
00200
00201 int dofNd1 = theNodes[0]->getNumberDOF();
00202 int dofNd2 = theNodes[1]->getNumberDOF();
00203
00204 if (dofNd1 != 3 || dofNd2 != 3) {
00205
00206
00207
00208 return;
00209 }
00210
00211 if (crdTransf->initialize(theNodes[0], theNodes[1])) {
00212
00213 }
00214
00215 double L = crdTransf->getInitialLength();
00216
00217 if (L == 0.0) {
00218
00219 }
00220
00221 this->DomainComponent::setDomain(theDomain);
00222
00223 this->update();
00224 }
00225
00226 int
00227 DispBeamColumn2d::commitState()
00228 {
00229 int retVal = 0;
00230
00231
00232 if ((retVal = this->Element::commitState()) != 0) {
00233 opserr << "DispBeamColumn2d::commitState () - failed in base class";
00234 }
00235
00236
00237 for (int i = 0; i < numSections; i++)
00238 retVal += theSections[i]->commitState();
00239
00240 retVal += crdTransf->commitState();
00241
00242 return retVal;
00243 }
00244
00245 int
00246 DispBeamColumn2d::revertToLastCommit()
00247 {
00248 int retVal = 0;
00249
00250
00251 for (int i = 0; i < numSections; i++)
00252 retVal += theSections[i]->revertToLastCommit();
00253
00254 retVal += crdTransf->revertToLastCommit();
00255
00256 return retVal;
00257 }
00258
00259 int
00260 DispBeamColumn2d::revertToStart()
00261 {
00262 int retVal = 0;
00263
00264
00265 for (int i = 0; i < numSections; i++)
00266 retVal += theSections[i]->revertToStart();
00267
00268 retVal += crdTransf->revertToStart();
00269
00270 return retVal;
00271 }
00272
00273 int
00274 DispBeamColumn2d::update(void)
00275 {
00276
00277 crdTransf->update();
00278
00279
00280 const Vector &v = crdTransf->getBasicTrialDisp();
00281
00282 double L = crdTransf->getInitialLength();
00283 double oneOverL = 1.0/L;
00284
00285
00286 double xi[10];
00287 beamInt->getSectionLocations(numSections, L, xi);
00288
00289
00290 for (int i = 0; i < numSections; i++) {
00291
00292 int order = theSections[i]->getOrder();
00293 const ID &code = theSections[i]->getType();
00294
00295 Vector e(workArea, order);
00296
00297
00298 double xi6 = 6.0*xi[i];
00299
00300 int j;
00301 for (j = 0; j < order; j++) {
00302 switch(code(j)) {
00303 case SECTION_RESPONSE_P:
00304 e(j) = oneOverL*v(0); break;
00305 case SECTION_RESPONSE_MZ:
00306 e(j) = oneOverL*((xi6-4.0)*v(1) + (xi6-2.0)*v(2)); break;
00307 default:
00308 e(j) = 0.0; break;
00309 }
00310 }
00311
00312
00313 theSections[i]->setTrialSectionDeformation(e);
00314 }
00315
00316 return 0;
00317 }
00318
00319 const Matrix&
00320 DispBeamColumn2d::getTangentStiff()
00321 {
00322 static Matrix kb(3,3);
00323
00324
00325 kb.Zero();
00326 q.Zero();
00327
00328 double L = crdTransf->getInitialLength();
00329 double oneOverL = 1.0/L;
00330
00331
00332
00333 double xi[10];
00334 beamInt->getSectionLocations(numSections, L, xi);
00335 double wt[10];
00336 beamInt->getSectionWeights(numSections, L, wt);
00337
00338
00339 for (int i = 0; i < numSections; i++) {
00340
00341 int order = theSections[i]->getOrder();
00342 const ID &code = theSections[i]->getType();
00343
00344 Matrix ka(workArea, order, 3);
00345 ka.Zero();
00346
00347
00348 double xi6 = 6.0*xi[i];
00349
00350
00351 const Matrix &ks = theSections[i]->getSectionTangent();
00352 const Vector &s = theSections[i]->getStressResultant();
00353
00354
00355
00356
00357 double wti = wt[i]*oneOverL;
00358 double tmp;
00359 int j, k;
00360 for (j = 0; j < order; j++) {
00361 switch(code(j)) {
00362 case SECTION_RESPONSE_P:
00363 for (k = 0; k < order; k++)
00364 ka(k,0) += ks(k,j)*wti;
00365 break;
00366 case SECTION_RESPONSE_MZ:
00367 for (k = 0; k < order; k++) {
00368 tmp = ks(k,j)*wti;
00369 ka(k,1) += (xi6-4.0)*tmp;
00370 ka(k,2) += (xi6-2.0)*tmp;
00371 }
00372 break;
00373 default:
00374 break;
00375 }
00376 }
00377 for (j = 0; j < order; j++) {
00378 switch (code(j)) {
00379 case SECTION_RESPONSE_P:
00380 for (k = 0; k < 3; k++)
00381 kb(0,k) += ka(j,k);
00382 break;
00383 case SECTION_RESPONSE_MZ:
00384 for (k = 0; k < 3; k++) {
00385 tmp = ka(j,k);
00386 kb(1,k) += (xi6-4.0)*tmp;
00387 kb(2,k) += (xi6-2.0)*tmp;
00388 }
00389 break;
00390 default:
00391 break;
00392 }
00393 }
00394
00395
00396 double si;
00397 for (j = 0; j < order; j++) {
00398
00399 si = s(j)*wt[i];
00400 switch(code(j)) {
00401 case SECTION_RESPONSE_P:
00402 q(0) += si; break;
00403 case SECTION_RESPONSE_MZ:
00404 q(1) += (xi6-4.0)*si; q(2) += (xi6-2.0)*si; break;
00405 default:
00406 break;
00407 }
00408 }
00409
00410 }
00411
00412
00413 q(0) += q0[0];
00414 q(1) += q0[1];
00415 q(2) += q0[2];
00416
00417
00418 K = crdTransf->getGlobalStiffMatrix(kb, q);
00419
00420 return K;
00421 }
00422
00423 const Matrix&
00424 DispBeamColumn2d::getInitialBasicStiff()
00425 {
00426 static Matrix kb(3,3);
00427
00428
00429 kb.Zero();
00430
00431 double L = crdTransf->getInitialLength();
00432 double oneOverL = 1.0/L;
00433
00434
00435
00436 double xi[10];
00437 beamInt->getSectionLocations(numSections, L, xi);
00438 double wt[10];
00439 beamInt->getSectionWeights(numSections, L, wt);
00440
00441
00442 for (int i = 0; i < numSections; i++) {
00443
00444 int order = theSections[i]->getOrder();
00445 const ID &code = theSections[i]->getType();
00446
00447 Matrix ka(workArea, order, 3);
00448 ka.Zero();
00449
00450
00451 double xi6 = 6.0*xi[i];
00452
00453
00454 const Matrix &ks = theSections[i]->getInitialTangent();
00455
00456
00457
00458
00459 double wti = wt[i]*oneOverL;
00460 double tmp;
00461 int j, k;
00462 for (j = 0; j < order; j++) {
00463 switch(code(j)) {
00464 case SECTION_RESPONSE_P:
00465 for (k = 0; k < order; k++)
00466 ka(k,0) += ks(k,j)*wti;
00467 break;
00468 case SECTION_RESPONSE_MZ:
00469 for (k = 0; k < order; k++) {
00470 tmp = ks(k,j)*wti;
00471 ka(k,1) += (xi6-4.0)*tmp;
00472 ka(k,2) += (xi6-2.0)*tmp;
00473 }
00474 break;
00475 default:
00476 break;
00477 }
00478 }
00479 for (j = 0; j < order; j++) {
00480 switch (code(j)) {
00481 case SECTION_RESPONSE_P:
00482 for (k = 0; k < 3; k++)
00483 kb(0,k) += ka(j,k);
00484 break;
00485 case SECTION_RESPONSE_MZ:
00486 for (k = 0; k < 3; k++) {
00487 tmp = ka(j,k);
00488 kb(1,k) += (xi6-4.0)*tmp;
00489 kb(2,k) += (xi6-2.0)*tmp;
00490 }
00491 break;
00492 default:
00493 break;
00494 }
00495 }
00496
00497 }
00498
00499 return kb;
00500 }
00501
00502 const Matrix&
00503 DispBeamColumn2d::getInitialStiff()
00504 {
00505 const Matrix &kb = this->getInitialBasicStiff();
00506
00507
00508 K = crdTransf->getInitialGlobalStiffMatrix(kb);
00509
00510 return K;
00511 }
00512
00513 const Matrix&
00514 DispBeamColumn2d::getMass()
00515 {
00516 K.Zero();
00517
00518 if (rho == 0.0)
00519 return K;
00520
00521 double L = crdTransf->getInitialLength();
00522 double m = 0.5*rho*L;
00523
00524 K(0,0) = K(1,1) = K(3,3) = K(4,4) = m;
00525
00526 return K;
00527 }
00528
00529 void
00530 DispBeamColumn2d::zeroLoad(void)
00531 {
00532 Q.Zero();
00533
00534 q0[0] = 0.0;
00535 q0[1] = 0.0;
00536 q0[2] = 0.0;
00537
00538 p0[0] = 0.0;
00539 p0[1] = 0.0;
00540 p0[2] = 0.0;
00541
00542 return;
00543 }
00544
00545 int
00546 DispBeamColumn2d::addLoad(ElementalLoad *theLoad, double loadFactor)
00547 {
00548 int type;
00549 const Vector &data = theLoad->getData(type, loadFactor);
00550 double L = crdTransf->getInitialLength();
00551
00552 if (type == LOAD_TAG_Beam2dUniformLoad) {
00553 double wt = data(0)*loadFactor;
00554 double wa = data(1)*loadFactor;
00555
00556 double V = 0.5*wt*L;
00557 double M = V*L/6.0;
00558 double P = wa*L;
00559
00560
00561 p0[0] -= P;
00562 p0[1] -= V;
00563 p0[2] -= V;
00564
00565
00566 q0[0] -= 0.5*P;
00567 q0[1] -= M;
00568 q0[2] += M;
00569 }
00570 else if (type == LOAD_TAG_Beam2dPointLoad) {
00571 double P = data(0)*loadFactor;
00572 double N = data(1)*loadFactor;
00573 double aOverL = data(2);
00574
00575 if (aOverL < 0.0 || aOverL > 1.0)
00576 return 0;
00577
00578 double a = aOverL*L;
00579 double b = L-a;
00580
00581
00582 p0[0] -= N;
00583 double V1 = P*(1.0-aOverL);
00584 double V2 = P*aOverL;
00585 p0[1] -= V1;
00586 p0[2] -= V2;
00587
00588 double L2 = 1.0/(L*L);
00589 double a2 = a*a;
00590 double b2 = b*b;
00591
00592
00593 q0[0] -= N*aOverL;
00594 double M1 = -a * b2 * P * L2;
00595 double M2 = a2 * b * P * L2;
00596 q0[1] += M1;
00597 q0[2] += M2;
00598 }
00599 else {
00600 opserr << "DispBeamColumn2d::DispBeamColumn2d -- load type unknown for element with tag: "
00601 << this->getTag() << "DispBeamColumn2d::addLoad()\n";
00602
00603 return -1;
00604 }
00605
00606 return 0;
00607 }
00608
00609 int
00610 DispBeamColumn2d::addInertiaLoadToUnbalance(const Vector &accel)
00611 {
00612
00613 if (rho == 0.0)
00614 return 0;
00615
00616
00617 const Vector &Raccel1 = theNodes[0]->getRV(accel);
00618 const Vector &Raccel2 = theNodes[1]->getRV(accel);
00619
00620 if (3 != Raccel1.Size() || 3 != Raccel2.Size()) {
00621 opserr << "DispBeamColumn2d::addInertiaLoadToUnbalance matrix and vector sizes are incompatable\n";
00622 return -1;
00623 }
00624
00625 double L = crdTransf->getInitialLength();
00626 double m = 0.5*rho*L;
00627
00628
00629
00630 Q(0) -= m*Raccel1(0);
00631 Q(1) -= m*Raccel1(1);
00632 Q(3) -= m*Raccel2(0);
00633 Q(4) -= m*Raccel2(1);
00634
00635 return 0;
00636 }
00637
00638 const Vector&
00639 DispBeamColumn2d::getResistingForce()
00640 {
00641 double L = crdTransf->getInitialLength();
00642 double oneOverL = 1.0/L;
00643
00644
00645
00646 double xi[10];
00647 beamInt->getSectionLocations(numSections, L, xi);
00648 double wt[10];
00649 beamInt->getSectionWeights(numSections, L, wt);
00650
00651
00652 q.Zero();
00653
00654
00655 for (int i = 0; i < numSections; i++) {
00656
00657 int order = theSections[i]->getOrder();
00658 const ID &code = theSections[i]->getType();
00659
00660
00661 double xi6 = 6.0*xi[i];
00662
00663
00664 const Vector &s = theSections[i]->getStressResultant();
00665
00666
00667
00668
00669 double si;
00670 for (int j = 0; j < order; j++) {
00671
00672 si = s(j)*wt[i];
00673 switch(code(j)) {
00674 case SECTION_RESPONSE_P:
00675 q(0) += si; break;
00676 case SECTION_RESPONSE_MZ:
00677 q(1) += (xi6-4.0)*si; q(2) += (xi6-2.0)*si; break;
00678 default:
00679 break;
00680 }
00681 }
00682
00683 }
00684
00685
00686 q(0) += q0[0];
00687 q(1) += q0[1];
00688 q(2) += q0[2];
00689
00690
00691 Vector p0Vec(p0, 3);
00692
00693 P = crdTransf->getGlobalResistingForce(q, p0Vec);
00694
00695
00696
00697 P(0) -= Q(0);
00698 P(1) -= Q(1);
00699 P(2) -= Q(2);
00700 P(3) -= Q(3);
00701 P(4) -= Q(4);
00702 P(5) -= Q(5);
00703
00704 return P;
00705 }
00706
00707 const Vector&
00708 DispBeamColumn2d::getResistingForceIncInertia()
00709 {
00710
00711 this->getResistingForce();
00712
00713 if (rho != 0.0) {
00714 const Vector &accel1 = theNodes[0]->getTrialAccel();
00715 const Vector &accel2 = theNodes[1]->getTrialAccel();
00716
00717
00718 this->getResistingForce();
00719
00720 double L = crdTransf->getInitialLength();
00721 double m = 0.5*rho*L;
00722
00723 P(0) += m*accel1(0);
00724 P(1) += m*accel1(1);
00725 P(3) += m*accel2(0);
00726 P(4) += m*accel2(1);
00727
00728
00729 if (alphaM != 0.0 || betaK != 0.0 || betaK0 != 0.0 || betaKc != 0.0)
00730 P += this->getRayleighDampingForces();
00731
00732 } else {
00733
00734
00735 if (betaK != 0.0 || betaK0 != 0.0 || betaKc != 0.0)
00736 P += this->getRayleighDampingForces();
00737 }
00738
00739 return P;
00740 }
00741
00742 int
00743 DispBeamColumn2d::sendSelf(int commitTag, Channel &theChannel)
00744 {
00745
00746
00747 int dbTag = this->getDbTag();
00748 int i, j;
00749 int loc = 0;
00750
00751 static ID idData(7);
00752 idData(0) = this->getTag();
00753 idData(1) = connectedExternalNodes(0);
00754 idData(2) = connectedExternalNodes(1);
00755 idData(3) = numSections;
00756 idData(4) = crdTransf->getClassTag();
00757 int crdTransfDbTag = crdTransf->getDbTag();
00758 if (crdTransfDbTag == 0) {
00759 crdTransfDbTag = theChannel.getDbTag();
00760 if (crdTransfDbTag != 0)
00761 crdTransf->setDbTag(crdTransfDbTag);
00762 }
00763 idData(5) = crdTransfDbTag;
00764
00765 if (theChannel.sendID(dbTag, commitTag, idData) < 0) {
00766 opserr << "DispBeamColumn2d::sendSelf() - failed to send ID data\n";
00767 return -1;
00768 }
00769
00770
00771
00772 if (crdTransf->sendSelf(commitTag, theChannel) < 0) {
00773 opserr << "DispBeamColumn2d::sendSelf() - failed to send crdTranf\n";
00774 return -1;
00775 }
00776
00777
00778
00779
00780
00781
00782
00783 ID idSections(2*numSections);
00784 loc = 0;
00785 for (i = 0; i<numSections; i++) {
00786 int sectClassTag = theSections[i]->getClassTag();
00787 int sectDbTag = theSections[i]->getDbTag();
00788 if (sectDbTag == 0) {
00789 sectDbTag = theChannel.getDbTag();
00790 theSections[i]->setDbTag(sectDbTag);
00791 }
00792
00793 idSections(loc) = sectClassTag;
00794 idSections(loc+1) = sectDbTag;
00795 loc += 2;
00796 }
00797
00798 if (theChannel.sendID(dbTag, commitTag, idSections) < 0) {
00799 opserr << "DispBeamColumn2d::sendSelf() - failed to send ID data\n";
00800 return -1;
00801 }
00802
00803
00804
00805
00806
00807 for (j = 0; j<numSections; j++) {
00808 if (theSections[j]->sendSelf(commitTag, theChannel) < 0) {
00809 opserr << "DispBeamColumn2d::sendSelf() - section " <<
00810 j << "failed to send itself\n";
00811 return -1;
00812 }
00813 }
00814
00815 return 0;
00816 }
00817
00818 int
00819 DispBeamColumn2d::recvSelf(int commitTag, Channel &theChannel,
00820 FEM_ObjectBroker &theBroker)
00821 {
00822
00823
00824
00825 int dbTag = this->getDbTag();
00826 int i;
00827
00828 static ID idData(7);
00829
00830 if (theChannel.recvID(dbTag, commitTag, idData) < 0) {
00831 opserr << "DispBeamColumn2d::recvSelf() - failed to recv ID data\n";
00832 return -1;
00833 }
00834
00835 this->setTag(idData(0));
00836 connectedExternalNodes(0) = idData(1);
00837 connectedExternalNodes(1) = idData(2);
00838
00839 int crdTransfClassTag = idData(4);
00840 int crdTransfDbTag = idData(5);
00841
00842
00843 if (crdTransf == 0 || crdTransf->getClassTag() != crdTransfClassTag) {
00844 if (crdTransf != 0)
00845 delete crdTransf;
00846
00847 crdTransf = theBroker.getNewCrdTransf2d(crdTransfClassTag);
00848
00849 if (crdTransf == 0) {
00850 opserr << "DispBeamColumn2d::recvSelf() - failed to obtain a CrdTrans object with classTag " <<
00851 crdTransfClassTag << endln;
00852 return -2;
00853 }
00854 }
00855
00856 crdTransf->setDbTag(crdTransfDbTag);
00857
00858
00859 if (crdTransf->recvSelf(commitTag, theChannel, theBroker) < 0) {
00860 opserr << "DispBeamColumn2d::sendSelf() - failed to recv crdTranf\n";
00861 return -3;
00862 }
00863
00864
00865
00866
00867
00868 ID idSections(2*idData(3));
00869 int loc = 0;
00870
00871 if (theChannel.recvID(dbTag, commitTag, idSections) < 0) {
00872 opserr << "DispBeamColumn2d::recvSelf() - failed to recv ID data\n";
00873 return -1;
00874 }
00875
00876
00877
00878
00879
00880 if (numSections != idData(3)) {
00881
00882
00883
00884
00885
00886
00887
00888 if (numSections != 0) {
00889 for (int i=0; i<numSections; i++)
00890 delete theSections[i];
00891 delete [] theSections;
00892 }
00893
00894
00895 theSections = new SectionForceDeformation *[idData(3)];
00896 if (theSections == 0) {
00897 opserr << "DispBeamColumn2d::recvSelf() - out of memory creating sections array of size " <<
00898 idData(3) << endln;
00899 return -1;
00900 }
00901
00902
00903 numSections = idData(3);
00904 loc = 0;
00905
00906 for (i=0; i<numSections; i++) {
00907 int sectClassTag = idSections(loc);
00908 int sectDbTag = idSections(loc+1);
00909 loc += 2;
00910 theSections[i] = theBroker.getNewSection(sectClassTag);
00911 if (theSections[i] == 0) {
00912 opserr << "DispBeamColumn2d::recvSelf() - Broker could not create Section of class type " <<
00913 sectClassTag << endln;
00914 exit(-1);
00915 }
00916 theSections[i]->setDbTag(sectDbTag);
00917 if (theSections[i]->recvSelf(commitTag, theChannel, theBroker) < 0) {
00918 opserr << "DispBeamColumn2d::recvSelf() - section " << i << " failed to recv itself\n";
00919 return -1;
00920 }
00921 }
00922
00923 } else {
00924
00925
00926
00927
00928
00929
00930 loc = 0;
00931 for (i=0; i<numSections; i++) {
00932 int sectClassTag = idSections(loc);
00933 int sectDbTag = idSections(loc+1);
00934 loc += 2;
00935
00936
00937 if (theSections[i]->getClassTag() != sectClassTag) {
00938
00939 delete theSections[i];
00940 theSections[i] = theBroker.getNewSection(sectClassTag);
00941 if (theSections[i] == 0) {
00942 opserr << "DispBeamColumn2d::recvSelf() - Broker could not create Section of class type " <<
00943 sectClassTag << endln;
00944 exit(-1);
00945 }
00946 }
00947
00948
00949 theSections[i]->setDbTag(sectDbTag);
00950 if (theSections[i]->recvSelf(commitTag, theChannel, theBroker) < 0) {
00951 opserr << "DispBeamColumn2d::recvSelf() - section " << i << " failed to recv itself\n";
00952 return -1;
00953 }
00954 }
00955 }
00956
00957 return 0;
00958 }
00959
00960 void
00961 DispBeamColumn2d::Print(OPS_Stream &s, int flag)
00962 {
00963 s << "\nDispBeamColumn2d, element id: " << this->getTag() << endln;
00964 s << "\tConnected external nodes: " << connectedExternalNodes;
00965 s << "\tCoordTransf: " << crdTransf->getTag() << endln;
00966 s << "\tmass density: " << rho << endln;
00967
00968 double L = crdTransf->getInitialLength();
00969 double P = q(0);
00970 double M1 = q(1);
00971 double M2 = q(2);
00972 double V = (M1+M2)/L;
00973 s << "\tEnd 1 Forces (P V M): " << -P+p0[0]
00974 << " " << V+p0[1] << " " << M1 << endln;
00975 s << "\tEnd 2 Forces (P V M): " << P
00976 << " " << -V+p0[2] << " " << M2 << endln;
00977
00978 beamInt->Print(s, flag);
00979
00980 for (int i = 0; i < numSections; i++)
00981 theSections[i]->Print(s,flag);
00982 }
00983
00984
00985 int
00986 DispBeamColumn2d::displaySelf(Renderer &theViewer, int displayMode, float fact)
00987 {
00988
00989
00990 const Vector &end1Crd = theNodes[0]->getCrds();
00991 const Vector &end2Crd = theNodes[1]->getCrds();
00992
00993 static Vector v1(3);
00994 static Vector v2(3);
00995
00996 if (displayMode >= 0) {
00997 const Vector &end1Disp = theNodes[0]->getDisp();
00998 const Vector &end2Disp = theNodes[1]->getDisp();
00999
01000 for (int i = 0; i < 2; i++) {
01001 v1(i) = end1Crd(i) + end1Disp(i)*fact;
01002 v2(i) = end2Crd(i) + end2Disp(i)*fact;
01003 }
01004 } else {
01005 int mode = displayMode * -1;
01006 const Matrix &eigen1 = theNodes[0]->getEigenvectors();
01007 const Matrix &eigen2 = theNodes[1]->getEigenvectors();
01008 if (eigen1.noCols() >= mode) {
01009 for (int i = 0; i < 2; i++) {
01010 v1(i) = end1Crd(i) + eigen1(i,mode-1)*fact;
01011 v2(i) = end2Crd(i) + eigen2(i,mode-1)*fact;
01012 }
01013 } else {
01014 for (int i = 0; i < 2; i++) {
01015 v1(i) = end1Crd(i);
01016 v2(i) = end2Crd(i);
01017 }
01018 }
01019 }
01020
01021 return theViewer.drawLine (v1, v2, 1.0, 1.0);
01022 }
01023
01024 Response*
01025 DispBeamColumn2d::setResponse(const char **argv, int argc,
01026 Information &eleInfo, OPS_Stream &output)
01027 {
01028 Response *theResponse = 0;
01029
01030 output.tag("ElementOutput");
01031 output.attr("eleType","DispBeamColumn2d");
01032 output.attr("eleTag",this->getTag());
01033 output.attr("node1",connectedExternalNodes[0]);
01034 output.attr("node2",connectedExternalNodes[1]);
01035
01036
01037 if (strcmp(argv[0],"forces") == 0 || strcmp(argv[0],"force") == 0
01038 || strcmp(argv[0],"globalForce") == 0 || strcmp(argv[0],"globalForces") == 0) {
01039
01040 output.tag("ResponseType","Px_1");
01041 output.tag("ResponseType","Py_1");
01042 output.tag("ResponseType","Mz_1");
01043 output.tag("ResponseType","Px_2");
01044 output.tag("ResponseType","Py_2");
01045 output.tag("ResponseType","Mz_2");
01046
01047 theResponse = new ElementResponse(this, 1, P);
01048
01049
01050
01051 } else if (strcmp(argv[0],"localForce") == 0 || strcmp(argv[0],"localForces") == 0) {
01052
01053 output.tag("ResponseType","N1");
01054 output.tag("ResponseType","V1");
01055 output.tag("ResponseType","M1");
01056 output.tag("ResponseType","N2");
01057 output.tag("ResponseType","V2");
01058 output.tag("ResponseType","M2");
01059
01060 theResponse = new ElementResponse(this, 2, P);
01061
01062
01063
01064 } else if (strcmp(argv[0],"basicForce") == 0 || strcmp(argv[0],"basicForces") == 0) {
01065
01066 output.tag("ResponseType","N");
01067 output.tag("ResponseType","M1");
01068 output.tag("ResponseType","M2");
01069
01070 theResponse = new ElementResponse(this, 9, Vector(3));
01071
01072
01073 } else if (strcmp(argv[0],"chordRotation") == 0 || strcmp(argv[0],"chordDeformation") == 0
01074 || strcmp(argv[0],"basicDeformation") == 0) {
01075
01076 output.tag("ResponseType","eps");
01077 output.tag("ResponseType","theta1");
01078 output.tag("ResponseType","theta2");
01079
01080 theResponse = new ElementResponse(this, 3, Vector(3));
01081
01082
01083 } else if (strcmp(argv[0],"plasticRotation") == 0 || strcmp(argv[0],"plasticDeformation") == 0) {
01084
01085 output.tag("ResponseType","epsP");
01086 output.tag("ResponseType","theta1P");
01087 output.tag("ResponseType","theta2P");
01088
01089 theResponse = new ElementResponse(this, 4, Vector(3));
01090
01091
01092 } else if (strstr(argv[0],"section") != 0) {
01093 if (argc > 2) {
01094 int sectionNum = atoi(argv[1]);
01095 if (sectionNum > 0 && sectionNum <= numSections) {
01096
01097 output.tag("GaussPointOutput");
01098 output.attr("number",sectionNum);
01099 double xi[10];
01100 double L = crdTransf->getInitialLength();
01101 beamInt->getSectionLocations(numSections, L, xi);
01102 output.attr("eta",xi[sectionNum-1]*L);
01103
01104 theResponse = theSections[sectionNum-1]->setResponse(&argv[2], argc-2, eleInfo, output);
01105
01106 output.endTag();
01107 }
01108 }
01109 }
01110
01111
01112 else if (strcmp(argv[0],"dcurvdh") == 0)
01113 return new ElementResponse(this, 5, Vector(numSections));
01114
01115
01116 else if (strcmp(argv[0],"dvdh") == 0)
01117 return new ElementResponse(this, 6, Vector(3));
01118
01119 else if (strcmp(argv[0],"integrationPoints") == 0)
01120 return new ElementResponse(this, 7, Vector(numSections));
01121
01122 else if (strcmp(argv[0],"integrationWeights") == 0)
01123 return new ElementResponse(this, 8, Vector(numSections));
01124
01125 output.endTag();
01126 return theResponse;
01127 }
01128
01129 int
01130 DispBeamColumn2d::getResponse(int responseID, Information &eleInfo)
01131 {
01132 double V;
01133 double L = crdTransf->getInitialLength();
01134
01135 if (responseID == 1)
01136 return eleInfo.setVector(this->getResistingForce());
01137
01138 else if (responseID == 2) {
01139 P(3) = q(0);
01140 P(0) = -q(0)+p0[0];
01141 P(2) = q(1);
01142 P(5) = q(2);
01143 V = (q(1)+q(2))/L;
01144 P(1) = V+p0[1];
01145 P(4) = -V+p0[2];
01146 return eleInfo.setVector(P);
01147 }
01148
01149 else if (responseID == 9) {
01150 return eleInfo.setVector(q);
01151 }
01152
01153
01154 else if (responseID == 3)
01155 return eleInfo.setVector(crdTransf->getBasicTrialDisp());
01156
01157
01158 else if (responseID == 4) {
01159 static Vector vp(3);
01160 static Vector ve(3);
01161 const Matrix &kb = this->getInitialBasicStiff();
01162 kb.Solve(q, ve);
01163 vp = crdTransf->getBasicTrialDisp();
01164 vp -= ve;
01165 return eleInfo.setVector(vp);
01166 }
01167
01168
01169 else if (responseID == 5) {
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193 Vector curv(numSections);
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208 return eleInfo.setVector(curv);
01209 }
01210
01211
01212 else if (responseID == 6) {
01213 const Vector &dvdh = crdTransf->getBasicDisplSensitivity(1);
01214 return eleInfo.setVector(dvdh);
01215 }
01216
01217 else if (responseID == 7) {
01218
01219 double xi[10];
01220 beamInt->getSectionLocations(numSections, L, xi);
01221 Vector locs(numSections);
01222 for (int i = 0; i < numSections; i++)
01223 locs(i) = xi[i]*L;
01224 return eleInfo.setVector(locs);
01225 }
01226
01227 else if (responseID == 8) {
01228
01229 double wt[10];
01230 beamInt->getSectionWeights(numSections, L, wt);
01231 Vector weights(numSections);
01232 for (int i = 0; i < numSections; i++)
01233 weights(i) = wt[i]*L;
01234 return eleInfo.setVector(weights);
01235 }
01236
01237 else
01238 return -1;
01239 }
01240
01241
01242
01243 int
01244 DispBeamColumn2d::setParameter(const char **argv, int argc, Parameter ¶m)
01245 {
01246 if (argc < 1)
01247 return -1;
01248
01249
01250 if (strcmp(argv[0],"rho") == 0)
01251 return param.addObject(1, this);
01252
01253
01254 if (strstr(argv[0],"section") != 0) {
01255
01256 if (argc < 3)
01257 return -1;
01258
01259
01260 int paramSectionTag = atoi(argv[1]);
01261
01262
01263 int ok = 0;
01264 for (int i = 0; i < numSections; i++)
01265 if (paramSectionTag == theSections[i]->getTag())
01266 ok += theSections[i]->setParameter(&argv[2], argc-2, param);
01267
01268 return ok;
01269 }
01270
01271 else if (strstr(argv[0],"integration") != 0) {
01272
01273 if (argc < 2)
01274 return -1;
01275
01276 return beamInt->setParameter(&argv[1], argc-1, param);
01277 }
01278
01279 else {
01280 opserr << "DispBeamColumn2d::setParameter() - could not set parameter. " << endln;
01281 return -1;
01282 }
01283 }
01284
01285 int
01286 DispBeamColumn2d::updateParameter (int parameterID, Information &info)
01287 {
01288 if (parameterID == 1) {
01289 rho = info.theDouble;
01290 return 0;
01291 }
01292 else
01293 return -1;
01294 }
01295
01296
01297
01298
01299 int
01300 DispBeamColumn2d::activateParameter(int passedParameterID)
01301 {
01302 parameterID = passedParameterID;
01303
01304 return 0;
01305 }
01306
01307
01308
01309 const Matrix &
01310 DispBeamColumn2d::getKiSensitivity(int gradNumber)
01311 {
01312 K.Zero();
01313 return K;
01314 }
01315
01316 const Matrix &
01317 DispBeamColumn2d::getMassSensitivity(int gradNumber)
01318 {
01319 K.Zero();
01320 return K;
01321 }
01322
01323
01324
01325 const Vector &
01326 DispBeamColumn2d::getResistingForceSensitivity(int gradNumber)
01327 {
01328 double L = crdTransf->getInitialLength();
01329 double oneOverL = 1.0/L;
01330
01331
01332
01333 double xi[10];
01334 beamInt->getSectionLocations(numSections, L, xi);
01335 double wt[10];
01336 beamInt->getSectionWeights(numSections, L, wt);
01337
01338
01339 static Vector dqdh(3);
01340 dqdh.Zero();
01341
01342
01343 for (int i = 0; i < numSections; i++) {
01344
01345 int order = theSections[i]->getOrder();
01346 const ID &code = theSections[i]->getType();
01347
01348
01349 double xi6 = 6.0*xi[i];
01350
01351 double wti = wt[i];
01352
01353
01354 const Vector &dsdh = theSections[i]->getStressResultantSensitivity(gradNumber,true);
01355
01356
01357 double sensi;
01358 for (int j = 0; j < order; j++) {
01359 sensi = dsdh(j)*wti;
01360 switch(code(j)) {
01361 case SECTION_RESPONSE_P:
01362 dqdh(0) += sensi;
01363 break;
01364 case SECTION_RESPONSE_MZ:
01365 dqdh(1) += (xi6-4.0)*sensi;
01366 dqdh(2) += (xi6-2.0)*sensi;
01367 break;
01368 default:
01369 break;
01370 }
01371 }
01372 }
01373
01374
01375 static Vector dp0dh(3);
01376
01377 P.Zero();
01378
01380
01381 if (crdTransf->isShapeSensitivity()) {
01382
01383
01384
01385 static Matrix kbmine(3,3);
01386 kbmine.Zero();
01387 q.Zero();
01388
01389 double tmp;
01390
01391 int j, k;
01392
01393 for (int i = 0; i < numSections; i++) {
01394
01395 int order = theSections[i]->getOrder();
01396 const ID &code = theSections[i]->getType();
01397
01398
01399 double xi6 = 6.0*xi[i];
01400
01401 double wti = wt[i];
01402
01403 const Vector &s = theSections[i]->getStressResultant();
01404 const Matrix &ks = theSections[i]->getSectionTangent();
01405
01406 Matrix ka(workArea, order, 3);
01407 ka.Zero();
01408
01409 double si;
01410 for (j = 0; j < order; j++) {
01411 si = s(j)*wti;
01412 switch(code(j)) {
01413 case SECTION_RESPONSE_P:
01414 q(0) += si;
01415 for (k = 0; k < order; k++) {
01416 ka(k,0) += ks(k,j)*wti;
01417 }
01418 break;
01419 case SECTION_RESPONSE_MZ:
01420 q(1) += (xi6-4.0)*si;
01421 q(2) += (xi6-2.0)*si;
01422 for (k = 0; k < order; k++) {
01423 tmp = ks(k,j)*wti;
01424 ka(k,1) += (xi6-4.0)*tmp;
01425 ka(k,2) += (xi6-2.0)*tmp;
01426 }
01427 break;
01428 default:
01429 break;
01430 }
01431 }
01432 for (j = 0; j < order; j++) {
01433 switch (code(j)) {
01434 case SECTION_RESPONSE_P:
01435 for (k = 0; k < 3; k++) {
01436 kbmine(0,k) += ka(j,k);
01437 }
01438 break;
01439 case SECTION_RESPONSE_MZ:
01440 for (k = 0; k < 3; k++) {
01441 tmp = ka(j,k);
01442 kbmine(1,k) += (xi6-4.0)*tmp;
01443 kbmine(2,k) += (xi6-2.0)*tmp;
01444 }
01445 break;
01446 default:
01447 break;
01448 }
01449 }
01450 }
01451
01452 const Vector &A_u = crdTransf->getBasicTrialDisp();
01453 double dLdh = crdTransf->getdLdh();
01454 double d1overLdh = -dLdh/(L*L);
01455
01456 dqdh.addMatrixVector(1.0, kbmine, A_u, d1overLdh);
01457
01458
01459 const Vector &dAdh_u = crdTransf->getBasicTrialDispShapeSensitivity();
01460 dqdh.addMatrixVector(1.0, kbmine, dAdh_u, oneOverL);
01461
01462
01463 P += crdTransf->getGlobalResistingForceShapeSensitivity(q, dp0dh, gradNumber);
01464 }
01465
01466
01467 P += crdTransf->getGlobalResistingForce(dqdh, dp0dh);
01468
01469 return P;
01470 }
01471
01472
01473
01474
01475 int
01476 DispBeamColumn2d::commitSensitivity(int gradNumber, int numGrads)
01477 {
01478
01479 const Vector &v = crdTransf->getBasicTrialDisp();
01480
01481 static Vector dvdh(3);
01482 dvdh = crdTransf->getBasicDisplSensitivity(gradNumber);
01483
01484 double L = crdTransf->getInitialLength();
01485 double oneOverL = 1.0/L;
01486
01487 double xi[10];
01488 beamInt->getSectionLocations(numSections, L, xi);
01489
01490
01491 double d1oLdh = crdTransf->getd1overLdh();
01492
01493
01494 for (int i = 0; i < numSections; i++) {
01495
01496 int order = theSections[i]->getOrder();
01497 const ID &code = theSections[i]->getType();
01498
01499 Vector e(workArea, order);
01500
01501
01502 double xi6 = 6.0*xi[i];
01503
01504 for (int j = 0; j < order; j++) {
01505 switch(code(j)) {
01506 case SECTION_RESPONSE_P:
01507 e(j) = oneOverL*dvdh(0)
01508 + d1oLdh*v(0);
01509 break;
01510 case SECTION_RESPONSE_MZ:
01511 e(j) = oneOverL*((xi6-4.0)*dvdh(1) + (xi6-2.0)*dvdh(2))
01512 + d1oLdh*((xi6-4.0)*v(1) + (xi6-2.0)*v(2));
01513 break;
01514 default:
01515 e(j) = 0.0;
01516 break;
01517 }
01518 }
01519
01520
01521 theSections[i]->commitSensitivity(e,gradNumber,numGrads);
01522 }
01523
01524 return 0;
01525 }
01526
01527
01528
01529