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