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
00036 #include <TrussSection.h>
00037 #include <Information.h>
00038
00039 #include <string.h>
00040
00041 #include <Domain.h>
00042 #include <Node.h>
00043 #include <Channel.h>
00044 #include <FEM_ObjectBroker.h>
00045 #include <SectionForceDeformation.h>
00046 #include <ElementResponse.h>
00047
00048 #include <G3Globals.h>
00049
00050 #include <Renderer.h>
00051
00052 #include <math.h>
00053 #include <stdlib.h>
00054
00055
00056 Matrix TrussSection::trussM2(2,2);
00057 Matrix TrussSection::trussM3(3,3);
00058 Matrix TrussSection::trussM4(4,4);
00059 Matrix TrussSection::trussM6(6,6);
00060 Matrix TrussSection::trussM12(12,12);
00061 Vector TrussSection::trussV2(2);
00062 Vector TrussSection::trussV3(3);
00063 Vector TrussSection::trussV4(4);
00064 Vector TrussSection::trussV6(6);
00065 Vector TrussSection::trussV12(12);
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088 TrussSection::TrussSection(int tag,
00089 int dim,
00090 int Nd1, int Nd2,
00091 SectionForceDeformation &theSect,
00092 double rho)
00093 :Element(tag,ELE_TAG_TrussSection),
00094 connectedExternalNodes(2),
00095 dimension(dim), numDOF(0), theLoad(0),
00096 theMatrix(0), theVector(0), t(0),
00097 L(0.0), M(rho), end1Ptr(0), end2Ptr(0), theSection(0)
00098 {
00099
00100 theSection = theSect.getCopy();
00101 if (theSection == 0)
00102 g3ErrorHandler->fatal("FATAL TrussSection::TrussSection - failed to get a copy of material %d\n",
00103 theSect.getTag());
00104
00105 int order = theSection->getOrder();
00106 const ID &code = theSection->getType();
00107
00108 int i;
00109 for (i = 0; i < order; i++)
00110 if (code(i) == SECTION_RESPONSE_P)
00111 break;
00112
00113 if (i == order)
00114 g3ErrorHandler->warning("TrussSection::TrussSection - section does not provide axial response");
00115
00116
00117 if (connectedExternalNodes.Size() != 2)
00118 g3ErrorHandler->fatal("FATAL TrussSection::TrussSection - failed to create an ID of correct size\n");
00119 connectedExternalNodes(0) = Nd1;
00120 connectedExternalNodes(1) = Nd2;
00121 }
00122
00123
00124
00125
00126 TrussSection::TrussSection()
00127 :Element(0,ELE_TAG_TrussSection),
00128 connectedExternalNodes(2),
00129 dimension(0), numDOF(0),
00130 theMatrix(0), theVector(0), t(0),
00131 L(0.0), M(0.0), end1Ptr(0), end2Ptr(0), theSection(0)
00132 {
00133
00134 if (connectedExternalNodes.Size() != 2)
00135 g3ErrorHandler->fatal("FATAL TrussSection::TrussSection - failed to create an ID of correct size\n");
00136 }
00137
00138
00139
00140
00141 TrussSection::~TrussSection()
00142 {
00143 if (theSection != 0)
00144 delete theSection;
00145 if (t != 0)
00146 delete t;
00147 }
00148
00149
00150 int
00151 TrussSection::getNumExternalNodes(void) const
00152 {
00153 return 2;
00154 }
00155
00156 const ID &
00157 TrussSection::getExternalNodes(void)
00158 {
00159 return connectedExternalNodes;
00160 }
00161
00162 int
00163 TrussSection::getNumDOF(void)
00164 {
00165 return numDOF;
00166 }
00167
00168
00169
00170
00171
00172
00173
00174
00175 void
00176 TrussSection::setDomain(Domain *theDomain)
00177 {
00178
00179 if (theDomain == 0) {
00180 end1Ptr = 0;
00181 end2Ptr = 0;
00182 L = 0;
00183 return;
00184 }
00185
00186
00187 int Nd1 = connectedExternalNodes(0);
00188 int Nd2 = connectedExternalNodes(1);
00189 end1Ptr = theDomain->getNode(Nd1);
00190 end2Ptr = theDomain->getNode(Nd2);
00191
00192
00193 if ((end1Ptr == 0) || (end2Ptr == 0)){
00194 if (end1Ptr == 0)
00195 g3ErrorHandler->warning("TrussSection::setDomain() - Nd1: %d does not exist in ",Nd1);
00196 else
00197 g3ErrorHandler->warning("TrussSection::setDomain() - Nd2: %d does not exist in ",Nd2);
00198
00199 g3ErrorHandler->warning("model for truss with id %d\n",this->getTag());
00200
00201
00202 numDOF = 2;
00203 theMatrix = &trussM2;
00204 theVector = &trussV2;
00205
00206 return;
00207 }
00208
00209
00210 int dofNd1 = end1Ptr->getNumberDOF();
00211 int dofNd2 = end2Ptr->getNumberDOF();
00212
00213 if (dofNd1 != dofNd2) {
00214 g3ErrorHandler->warning("WARNING TrussSection::setDomain(): nodes %d and %d %s %d\n",Nd1, Nd2,
00215 "have differing dof at ends for truss",this->getTag());
00216
00217
00218 numDOF = 2;
00219 theMatrix = &trussM2;
00220 theVector = &trussV2;
00221
00222 return;
00223 }
00224
00225
00226 this->DomainComponent::setDomain(theDomain);
00227
00228
00229 if (dimension == 1 && dofNd1 == 1) {
00230 numDOF = 2;
00231 theMatrix = &trussM2;
00232 theVector = &trussV2;
00233 }
00234 else if (dimension == 2 && dofNd1 == 2) {
00235 numDOF = 4;
00236 theMatrix = &trussM4;
00237 theVector = &trussV4;
00238 }
00239 else if (dimension == 2 && dofNd1 == 3) {
00240 numDOF = 6;
00241 theMatrix = &trussM6;
00242 theVector = &trussV6;
00243 }
00244 else if (dimension == 3 && dofNd1 == 3) {
00245 numDOF = 6;
00246 theMatrix = &trussM6;
00247 theVector = &trussV6;
00248 }
00249 else if (dimension == 3 && dofNd1 == 6) {
00250 numDOF = 12;
00251 theMatrix = &trussM12;
00252 theVector = &trussV12;
00253 }
00254 else {
00255 g3ErrorHandler->warning("WARNING TrussSection::setDomain cannot handle %d dofs at nodes in %d d problem\n",
00256 dimension,dofNd1);
00257
00258 numDOF = 2;
00259 theMatrix = &trussM2;
00260 theVector = &trussV2;
00261 return;
00262 }
00263
00264
00265 t = new Matrix(1,numDOF);
00266 if (t == 0 || (t->noCols() != numDOF)) {
00267 g3ErrorHandler->fatal("FATAL TrussSection::setDomain out of memory creating T matrix (1 x %d)\n",numDOF);
00268 return;
00269 }
00270
00271
00272
00273 const Vector &end1Crd = end1Ptr->getCrds();
00274 const Vector &end2Crd = end2Ptr->getCrds();
00275
00276 if (dimension == 1) {
00277 Matrix &trans = *t;
00278 trans(0,0) = -1;
00279 trans(0,1) = 1;
00280
00281 double dx = end2Crd(0)-end1Crd(0);
00282 L = sqrt(dx*dx);
00283
00284 if (L == 0.0) {
00285 g3ErrorHandler->warning("WARNING TrussSection::setDomain() - truss %d has zero length\n",
00286 this->getTag());
00287 return;
00288 }
00289
00290 } else if (dimension == 2) {
00291 double dx = end2Crd(0)-end1Crd(0);
00292 double dy = end2Crd(1)-end1Crd(1);
00293
00294 L = sqrt(dx*dx + dy*dy);
00295
00296 if (L == 0.0) {
00297 g3ErrorHandler->warning("WARNING TrussSection::setDomain() - truss %d has zero length\n",
00298 this->getTag());
00299 return;
00300 }
00301
00302 double cs = dx/L;
00303 double sn = dy/L;
00304
00305 Matrix &trans = *t;
00306 if (numDOF == 4) {
00307 trans(0,0) = -cs;
00308 trans(0,1) = -sn;
00309 trans(0,2) = cs;
00310 trans(0,3) = sn;
00311 } else {
00312 trans(0,0) = -cs;
00313 trans(0,1) = -sn;
00314 trans(0,2) = 0.0;
00315 trans(0,3) = cs;
00316 trans(0,4) = sn;
00317 trans(0,5) = 0.0;
00318 }
00319
00320 } else {
00321 double dx = end2Crd(0)-end1Crd(0);
00322 double dy = end2Crd(1)-end1Crd(1);
00323 double dz = end2Crd(2)-end1Crd(2);
00324
00325 L = sqrt(dx*dx + dy*dy + dz*dz);
00326
00327 if (L == 0.0) {
00328 g3ErrorHandler->warning("WARNING TrussSection::setDomain() - truss %d has zero length\n",
00329 this->getTag());
00330 return;
00331 }
00332
00333 double cx = dx/L;
00334 double cy = dy/L;
00335 double cz = dz/L;
00336
00337 Matrix &trans = *t;
00338 if (numDOF == 6) {
00339 trans(0,0) = -cx;
00340 trans(0,1) = -cy;
00341 trans(0,2) = -cz;
00342 trans(0,3) = cx;
00343 trans(0,4) = cy;
00344 trans(0,5) = cz;
00345 } else {
00346 trans(0,0) = -cx;
00347 trans(0,1) = -cy;
00348 trans(0,2) = -cz;
00349 trans(0,3) = 0;
00350 trans(0,4) = 0;
00351 trans(0,5) = 0;
00352 trans(0,6) = cx;
00353 trans(0,7) = cy;
00354 trans(0,8) = cz;
00355 trans(0,9) = 0;
00356 trans(0,10) = 0;
00357 trans(0,11) = 0;
00358 }
00359 }
00360
00361
00362
00363 theLoad = new Vector(numDOF);
00364 if (theLoad == 0) {
00365 g3ErrorHandler->fatal("TrussSection::setDomain - truss %d %s %d\n",
00366 this->getTag(),
00367 "out of memory creating vector of size",
00368 numDOF);
00369 return;
00370 }
00371
00372
00373
00374 M = M * L/2;
00375
00376 this->update();
00377 }
00378
00379
00380 int
00381 TrussSection::commitState()
00382 {
00383 return theSection->commitState();
00384 }
00385
00386 int
00387 TrussSection::revertToLastCommit()
00388 {
00389 return theSection->revertToLastCommit();
00390 }
00391
00392 int
00393 TrussSection::revertToStart()
00394 {
00395 return theSection->revertToStart();
00396 }
00397
00398
00399
00400
00401 int
00402 TrussSection::update()
00403 {
00404 if (L == 0.0) {
00405 return -1;
00406 }
00407
00408
00409 double strain = this->computeCurrentStrain();
00410
00411 int order = theSection->getOrder();
00412 const ID &code = theSection->getType();
00413
00414 Vector e (order);
00415
00416 int i;
00417 for (i = 0; i < order; i++) {
00418 if (code(i) == SECTION_RESPONSE_P)
00419 e(i) = strain;
00420 }
00421
00422 return theSection->setTrialSectionDeformation(e);
00423 }
00424
00425
00426 const Matrix &
00427 TrussSection::getTangentStiff(void)
00428 {
00429 if (L == 0.0) {
00430 theMatrix->Zero();
00431 return *theMatrix;
00432 }
00433
00434 int order = theSection->getOrder();
00435 const ID &code = theSection->getType();
00436
00437 const Matrix &k = theSection->getSectionTangent();
00438 double AE = 0.0;
00439 for (int i = 0; i < order; i++) {
00440 if (code(i) == SECTION_RESPONSE_P)
00441 AE += k(i,i);
00442 }
00443
00444
00445 Matrix &stiff = *theMatrix;
00446 Matrix &trans = *t;
00447
00448 stiff = trans^trans;
00449
00450 stiff *= AE/L;
00451
00452 return *theMatrix;
00453 }
00454
00455 const Matrix &
00456 TrussSection::getSecantStiff(void)
00457 {
00458 return this->getTangentStiff();
00459 }
00460
00461 const Matrix &
00462 TrussSection::getDamp(void)
00463 {
00464 theMatrix->Zero();
00465 return *theMatrix;
00466 }
00467
00468
00469 const Matrix &
00470 TrussSection::getMass(void)
00471 {
00472 theMatrix->Zero();
00473
00474
00475 if (L == 0.0 || M == 0.0) {
00476 return *theMatrix;
00477 }
00478
00479 Matrix &mass = *theMatrix;
00480 if (dimension == 1 && numDOF == 2) {
00481 mass(0,0) = M;
00482 mass(1,1) = M;
00483 }
00484 else if (dimension == 2 && numDOF == 4) {
00485 mass(0,0) = M;
00486 mass(1,1) = M;
00487 mass(2,2) = M;
00488 mass(3,3) = M;
00489 }
00490 else if (dimension == 2 && numDOF == 6) {
00491 mass(0,0) = M;
00492 mass(1,1) = M;
00493 mass(2,2) = 0;
00494 mass(3,3) = M;
00495 mass(4,4) = M;
00496 mass(5,5) = 0;
00497 }
00498 else if (dimension == 3 && numDOF == 6) {
00499 mass(0,0) = M;
00500 mass(1,1) = M;
00501 mass(2,2) = M;
00502 mass(3,3) = M;
00503 mass(4,4) = M;
00504 mass(5,5) = M;
00505 }
00506 else if (dimension == 3 && numDOF == 12) {
00507 mass(0,0) = M;
00508 mass(1,1) = M;
00509 mass(2,2) = M;
00510 mass(3,3) = 0;
00511 mass(4,4) = 0;
00512 mass(5,5) = 0;
00513 mass(6,6) = M;
00514 mass(7,7) = M;
00515 mass(8,8) = M;
00516 mass(9,9) = 0;
00517 mass(10,10) = 0;
00518 mass(11,11) = 0;
00519 }
00520
00521 return *theMatrix;
00522 }
00523
00524
00525
00526 void
00527 TrussSection::zeroLoad(void)
00528 {
00529 theLoad->Zero();
00530 }
00531
00532
00533 int
00534 TrussSection::addLoad(const Vector &addP)
00535 {
00536 #ifdef _G3DEBUG
00537 if (dimension != addP.Size()) {
00538 g3ErrorHandler->warning("TrussSection::addPtoUnbalance %s\n",
00539 "matrix and vector sizes are incompatable");
00540 return -1;
00541 }
00542 #endif
00543 (*theLoad) += addP;
00544 return 0;
00545 }
00546
00547 int
00548 TrussSection::addInertiaLoadToUnbalance(const Vector &accel)
00549 {
00550
00551 if (L == 0.0 || M == 0.0)
00552 return 0;
00553
00554
00555 const Vector &Raccel1 = end1Ptr->getRV(accel);
00556 const Vector &Raccel2 = end2Ptr->getRV(accel);
00557
00558 int nodalDOF = numDOF/2;
00559
00560 #ifdef _G3DEBUG
00561 if (nodalDOF != Raccel1.Size() || nodalDOF != Raccel2.Size()) {
00562 g3ErrorHandler->warning("TrussSection::addInertiaLoadToUnbalance %s\n",
00563 "matrix and vector sizes are incompatable");
00564 return -1;
00565 }
00566 #endif
00567
00568
00569 for (int i=0; i<dimension; i++) {
00570 double val1 = Raccel1(i);
00571 double val2 = Raccel2(i);
00572
00573
00574 val1 *= -M;
00575 val2 *= -M;
00576
00577 (*theLoad)(i) += val1;
00578 (*theLoad)(i+nodalDOF) += val2;
00579 }
00580
00581 return 0;
00582 }
00583
00584
00585 const Vector &
00586 TrussSection::getResistingForce()
00587 {
00588 if (L == 0.0) {
00589 theVector->Zero();
00590 return *theVector;
00591 }
00592
00593 int order = theSection->getOrder();
00594 const ID &code = theSection->getType();
00595
00596 const Vector &s = theSection->getStressResultant();
00597 double force = 0.0;
00598 int i;
00599 for (i = 0; i < order; i++) {
00600 if (code(i) == SECTION_RESPONSE_P)
00601 force += s(i);
00602 }
00603
00604 for (i=0; i<numDOF; i++)
00605 (*theVector)(i) = (*t)(0,i)*force;
00606
00607
00608 (*theVector) -= *theLoad;
00609
00610 return *theVector;
00611 }
00612
00613
00614 const Vector &
00615 TrussSection::getResistingForceIncInertia()
00616 {
00617 this->getResistingForce();
00618
00619
00620 if (L != 0.0 && M != 0.0) {
00621
00622
00623 const Vector &accel1 = end1Ptr->getTrialAccel();
00624 const Vector &accel2 = end2Ptr->getTrialAccel();
00625
00626 int dof = dimension;
00627 int start = numDOF/2;
00628 for (int i=0; i<dof; i++) {
00629 (*theVector)(i) = (*theVector)(i) - M*accel1(i);
00630 (*theVector)(i+start) = (*theVector)(i+start) - M*accel2(i);
00631 }
00632 }
00633
00634 return *theVector;
00635 }
00636
00637
00638 int
00639 TrussSection::sendSelf(int commitTag, Channel &theChannel)
00640 {
00641 int res;
00642
00643
00644
00645
00646 int dataTag = this->getDbTag();
00647
00648
00649
00650
00651 static Vector data(6);
00652 data(0) = this->getTag();
00653 data(1) = dimension;
00654 data(2) = numDOF;
00655 if (L != 0)
00656 data(3) = M * 2 / (L);
00657 else
00658 data(3) = M;
00659 data(4) = theSection->getClassTag();
00660 int matDbTag = theSection->getDbTag();
00661
00662
00663
00664 if (matDbTag == 0) {
00665 matDbTag = theChannel.getDbTag();
00666 if (matDbTag != 0)
00667 theSection->setDbTag(matDbTag);
00668 }
00669 data(5) = matDbTag;
00670
00671 res = theChannel.sendVector(dataTag, commitTag, data);
00672 if (res < 0) {
00673 g3ErrorHandler->warning("WARNING TrussSection::sendSelf() - %d failed to send Vector\n",this->getTag());
00674 return -1;
00675 }
00676
00677
00678
00679 res = theChannel.sendID(dataTag, commitTag, connectedExternalNodes);
00680 if (res < 0) {
00681 g3ErrorHandler->warning("WARNING TrussSection::sendSelf() - %d failed to send ID\n",this->getTag());
00682 return -2;
00683 }
00684
00685
00686
00687 res = theSection->sendSelf(commitTag, theChannel);
00688 if (res < 0) {
00689 g3ErrorHandler->warning("WARNING TrussSection::sendSelf() - %d failed to send its Section\n",this->getTag());
00690 return -3;
00691 }
00692
00693 return 0;
00694 }
00695
00696 int
00697 TrussSection::recvSelf(int commitTag, Channel &theChannel, FEM_ObjectBroker &theBroker)
00698 {
00699
00700 int res;
00701 int dataTag = this->getDbTag();
00702
00703
00704
00705
00706 static Vector data(6);
00707 res = theChannel.recvVector(dataTag, commitTag, data);
00708 if (res < 0) {
00709 g3ErrorHandler->warning("WARNING TrussSection::recvSelf() - failed to receive Vector\n");
00710 return -1;
00711 }
00712
00713 this->setTag((int)data(0));
00714 dimension = data(1);
00715 numDOF = data(2);
00716 M = data(3);
00717
00718
00719 res = theChannel.recvID(dataTag, commitTag, connectedExternalNodes);
00720 if (res < 0) {
00721 g3ErrorHandler->warning("WARNING TrussSection::recvSelf() - %d failed to receive ID\n", this->getTag());
00722 return -2;
00723 }
00724
00725
00726
00727 int sectClass = data(4);
00728 int sectDb = data(5);
00729
00730
00731 if (theSection == 0)
00732 theSection = theBroker.getNewSection(sectClass);
00733
00734
00735 else if (theSection->getClassTag() != sectClass) {
00736 delete theSection;
00737 theSection = theBroker.getNewSection(sectClass);
00738 }
00739
00740
00741 if (theSection == 0) {
00742 g3ErrorHandler->warning("WARNING TrussSection::recvSelf() - %d failed to get a blank Section of type %d\n",
00743 this->getTag(), sectClass);
00744 return -3;
00745 }
00746
00747 theSection->setDbTag(sectDb);
00748 res = theSection->recvSelf(commitTag, theChannel, theBroker);
00749 if (res < 0) {
00750 g3ErrorHandler->warning("WARNING TrussSection::recvSelf() - %d failed to receive its Section\n", this->getTag());
00751 return -3;
00752 }
00753
00754 return 0;
00755 }
00756
00757
00758 int
00759 TrussSection::displaySelf(Renderer &theViewer, int displayMode, float fact)
00760 {
00761
00762 if (L == 0.0)
00763 return 0;
00764
00765
00766
00767
00768 const Vector &end1Crd = end1Ptr->getCrds();
00769 const Vector &end2Crd = end2Ptr->getCrds();
00770 const Vector &end1Disp = end1Ptr->getDisp();
00771 const Vector &end2Disp = end2Ptr->getDisp();
00772
00773 if (displayMode == 1 || displayMode == 2) {
00774 static Vector v1(3);
00775 static Vector v2(3);
00776 for (int i=0; i<dimension; i++) {
00777 v1(i) = end1Crd(i)+end1Disp(i)*fact;
00778 v2(i) = end2Crd(i)+end2Disp(i)*fact;
00779 }
00780
00781
00782 double strain, force;
00783 if (L == 0.0) {
00784 strain = 0.0;
00785 force = 0.0;
00786 } else {
00787 strain = this->computeCurrentStrain();
00788
00789 int order = theSection->getOrder();
00790 const ID &code = theSection->getType();
00791
00792 Vector e (order);
00793
00794 int i;
00795 for (i = 0; i < order; i++) {
00796 if (code(i) == SECTION_RESPONSE_P)
00797 e(i) = strain;
00798 }
00799
00800 theSection->setTrialSectionDeformation(e);
00801
00802 const Vector &s = theSection->getStressResultant();
00803 for (i = 0; i < order; i++) {
00804 if (code(i) == SECTION_RESPONSE_P)
00805 force += s(i);
00806 }
00807 }
00808
00809 if (displayMode == 2)
00810 return theViewer.drawLine(v1, v2, strain, strain);
00811 else {
00812 return theViewer.drawLine(v1,v2, force, force);
00813 }
00814 }
00815 return 0;
00816 }
00817
00818
00819 void
00820 TrussSection::Print(ostream &s, int flag)
00821 {
00822
00823 double strain, force;
00824 if (L == 0.0) {
00825 strain = 0;
00826 force = 0.0;
00827 } else {
00828 strain = this->computeCurrentStrain();
00829
00830 int order = theSection->getOrder();
00831 const ID &code = theSection->getType();
00832
00833 Vector e (order);
00834
00835 int i;
00836 for (i = 0; i < order; i++) {
00837 if (code(i) == SECTION_RESPONSE_P)
00838 e(i) = strain;
00839 }
00840
00841 theSection->setTrialSectionDeformation(e);
00842
00843 const Vector &s = theSection->getStressResultant();
00844 for (i = 0; i < order; i++) {
00845 if (code(i) == SECTION_RESPONSE_P)
00846 force += s(i);
00847 }
00848 }
00849
00850 for (int i=0; i<numDOF; i++)
00851 (*theVector)(i) = (*t)(0,i)*force;
00852
00853 if (flag == 0) {
00854 s << "Element: " << this->getTag();
00855 s << " type: TrussSection iNode: " << connectedExternalNodes(0);
00856 s << " jNode: " << connectedExternalNodes(1);
00857 s << " Total Mass: " << M*2;
00858
00859 s << " \n\t strain: " << strain;
00860 s << " axial load: " << force;
00861 if (theVector != 0)
00862 s << " \n\t unbalanced load: " << *theVector;
00863 s << " \t Section: " << *theSection;
00864 s << endl;
00865 } else if (flag == 1) {
00866 s << this->getTag() << " " << strain << " ";
00867 s << force << endl;
00868 }
00869 }
00870
00871 double
00872 TrussSection::computeCurrentStrain(void) const
00873 {
00874
00875
00876
00877 const Vector &disp1 = end1Ptr->getTrialDisp();
00878 const Vector &disp2 = end2Ptr->getTrialDisp();
00879
00880 double dLength = 0.0;
00881 for (int i=0; i<dimension; i++){
00882 dLength -= (disp2(i)-disp1(i))* (*t)(0,i);
00883 }
00884
00885
00886 return dLength/L;
00887 }
00888
00889 Response*
00890 TrussSection::setResponse(char **argv, int argc, Information &eleInformation)
00891 {
00892
00893
00894
00895
00896
00897 if (strcmp(argv[0],"force") == 0 || strcmp(argv[0],"forces") == 0 ||
00898 strcmp(argv[0],"axialForce") == 0) {
00899 eleInformation.theType = DoubleType;
00900 return new ElementResponse(this, 1);
00901 }
00902
00903 else if (strcmp(argv[0],"defo") == 0 || strcmp(argv[0],"deformations") == 0 ||
00904 strcmp(argv[0],"deformation") == 0) {
00905 eleInformation.theType = DoubleType;
00906 return new ElementResponse(this, 2);
00907 }
00908
00909
00910 else if (strcmp(argv[0],"stiff") ==0) {
00911 Matrix *newMatrix = new Matrix(*theMatrix);
00912 if (newMatrix == 0) {
00913 g3ErrorHandler->warning("WARNING TrussSection::setResponse() - %d out of memory creating matrix\n",
00914 this->getTag());
00915 return 0;
00916 }
00917
00918 eleInformation.theMatrix = newMatrix;
00919 eleInformation.theType = MatrixType;
00920 return new ElementResponse(this, 3);
00921 }
00922
00923
00924 else if (strcmp(argv[0],"section") ==0)
00925 return theSection->setResponse(&argv[1], argc-1, eleInformation);
00926
00927
00928 else
00929 return 0;
00930 }
00931
00932 int
00933 TrussSection::getResponse(int responseID, Information &eleInformation)
00934 {
00935 double strain, force;
00936
00937 switch (responseID) {
00938 case 1:
00939 if (L == 0.0) {
00940 strain = 0;
00941 force = 0.0;
00942 } else {
00943 strain = this->computeCurrentStrain();
00944 int order = theSection->getOrder();
00945 const ID &code = theSection->getType();
00946
00947 Vector e (order);
00948
00949 int i;
00950 for (i = 0; i < order; i++) {
00951 if (code(i) == SECTION_RESPONSE_P)
00952 e(i) = strain;
00953 }
00954
00955 theSection->setTrialSectionDeformation(e);
00956
00957 const Vector &s = theSection->getStressResultant();
00958 for (i = 0; i < order; i++) {
00959 if (code(i) == SECTION_RESPONSE_P)
00960 force += s(i);
00961 }
00962
00963 }
00964 eleInformation.theDouble = force;
00965 return 0;
00966
00967 case 2:
00968 if (L == 0.0) {
00969 strain = 0;
00970 } else {
00971 strain = this->computeCurrentStrain();
00972 }
00973 eleInformation.theDouble = strain*L;
00974 return 0;
00975
00976 case 3:
00977 if (L == 0.0) {
00978 theMatrix->Zero();
00979 *(eleInformation.theMatrix) = *theMatrix;
00980 return 0;
00981 } else {
00982
00983
00984 strain = this->computeCurrentStrain();
00985
00986 int order = theSection->getOrder();
00987 const ID &code = theSection->getType();
00988
00989 Vector e (order);
00990
00991 int i;
00992 for (i = 0; i < order; i++) {
00993 if (code(i) == SECTION_RESPONSE_P)
00994 e(i) = strain;
00995 }
00996
00997 theSection->setTrialSectionDeformation(e);
00998
00999 const Matrix &k = theSection->getSectionTangent();
01000 double AE = 0.0;
01001 for (i = 0; i < order; i++) {
01002 if (code(i) == SECTION_RESPONSE_P)
01003 AE += k(i,i);
01004 }
01005
01006
01007 Matrix &stiff = *theMatrix;
01008 Matrix &trans = *t;
01009 stiff = trans^trans;
01010 stiff *= AE/L;
01011 *(eleInformation.theMatrix) = *theMatrix;
01012 return 0;
01013 }
01014
01015 default:
01016 if (responseID >= 100)
01017 return theSection->getResponse(responseID-100, eleInformation);
01018 else
01019 return -1;
01020 }
01021 }
01022
01023 int
01024 TrussSection::setParameter (char **argv, int argc, Information &info)
01025 {
01026
01027 if (strcmp(argv[0],"section") == 0) {
01028 int ok = theSection->setParameter(&argv[1], argc-1, info);
01029 if (ok < 0)
01030 return -1;
01031 else
01032 return ok + 100;
01033 }
01034
01035
01036 else
01037 return -1;
01038
01039 }
01040
01041 int
01042 TrussSection::updateParameter (int parameterID, Information &info)
01043 {
01044 switch (parameterID) {
01045 case -1:
01046 return -1;
01047
01048 default:
01049 if (parameterID >= 100)
01050 return theSection->updateParameter(parameterID-100, info);
01051 else
01052 return -1;
01053 }
01054 }