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 #include <ZeroLengthSection.h>
00032 #include <Information.h>
00033
00034 #include <Domain.h>
00035 #include <Node.h>
00036 #include <Channel.h>
00037 #include <FEM_ObjectBroker.h>
00038 #include <SectionForceDeformation.h>
00039 #include <Renderer.h>
00040 #include <ElementResponse.h>
00041
00042 #include <G3Globals.h>
00043
00044 #include <math.h>
00045 #include <stdlib.h>
00046 #include <string.h>
00047
00048 Matrix ZeroLengthSection::K6(6,6);
00049 Matrix ZeroLengthSection::K12(12,12);
00050
00051 Vector ZeroLengthSection::P6(6);
00052 Vector ZeroLengthSection::P12(12);
00053
00054
00055
00056
00057
00058 ZeroLengthSection::ZeroLengthSection(int tag, int dim, int Nd1, int Nd2,
00059 const Vector& x, const Vector& yprime,
00060 SectionForceDeformation& sec) :
00061 Element(tag, ELE_TAG_ZeroLengthSection),
00062 connectedExternalNodes(2),
00063 dimension(dim), numDOF(0),
00064 transformation(3,3), v(0), K(0), P(0), A(0),
00065 end1Ptr(0), end2Ptr(0), theSection(0), order(0)
00066 {
00067
00068 theSection = sec.getCopy();
00069
00070 if (theSection == 0)
00071 g3ErrorHandler->fatal("%s -- failed to get copy of section",
00072 "ZeroLengthSection::ZeroLengthSection");
00073
00074
00075 order = theSection->getOrder();
00076
00077
00078 this->setUp(Nd1, Nd2, x, yprime);
00079 }
00080
00081 ZeroLengthSection::ZeroLengthSection() :
00082 Element(0, ELE_TAG_ZeroLengthSection),
00083 connectedExternalNodes(2),
00084 dimension(0), numDOF(0),
00085 transformation(3,3), v(0), K(0), P(0), A(0),
00086 end1Ptr(0), end2Ptr(0), theSection(0), order(0)
00087 {
00088
00089 }
00090
00091 ZeroLengthSection::~ZeroLengthSection()
00092 {
00093
00094
00095
00096 if (theSection != 0)
00097 delete theSection;
00098 if (A != 0)
00099 delete A;
00100 if (v != 0)
00101 delete v;
00102 }
00103
00104 int
00105 ZeroLengthSection::getNumExternalNodes(void) const
00106 {
00107 return 2;
00108 }
00109
00110 const ID &
00111 ZeroLengthSection::getExternalNodes(void)
00112 {
00113 return connectedExternalNodes;
00114 }
00115
00116 int
00117 ZeroLengthSection::getNumDOF(void)
00118 {
00119 return numDOF;
00120 }
00121
00122
00123
00124
00125
00126
00127
00128 void
00129 ZeroLengthSection::setDomain(Domain *theDomain)
00130 {
00131
00132 if (theDomain == 0) {
00133 end1Ptr = 0;
00134 end2Ptr = 0;
00135 return;
00136 }
00137
00138
00139 int Nd1 = connectedExternalNodes(0);
00140 int Nd2 = connectedExternalNodes(1);
00141 end1Ptr = theDomain->getNode(Nd1);
00142 end2Ptr = theDomain->getNode(Nd2);
00143
00144
00145 if (end1Ptr == 0 || end2Ptr == 0) {
00146 if (end1Ptr == 0)
00147 g3ErrorHandler->warning("%s -- Nd1: %d does not exist in ",
00148 "ZeroLengthSection::setDomain()", Nd1);
00149 else
00150 g3ErrorHandler->warning("%s -- Nd2: %d does not exist in ",
00151 "ZeroLengthSection::setDomain()", Nd2);
00152
00153 g3ErrorHandler->warning("model for ZeroLengthSection with id %d",
00154 this->getTag());
00155
00156 return;
00157 }
00158
00159
00160 int dofNd1 = end1Ptr->getNumberDOF();
00161 int dofNd2 = end2Ptr->getNumberDOF();
00162
00163
00164 if (dofNd1 != dofNd2) {
00165 g3ErrorHandler->warning("%s -- nodes %d and %d %s %d\n",Nd1, Nd2,
00166 "ZeroLengthSection::setDomain()",
00167 "have differing dof at ends for ZeroLengthSection ",
00168 this->getTag());
00169 return;
00170 }
00171
00172 numDOF = 2*dofNd1;
00173
00174 if (numDOF != 6 && numDOF != 12)
00175 g3ErrorHandler->warning("%s -- element only works for 3 (2d) or 6 (3d) dof per node"
00176 "ZeroLengthSection::setDomain()");
00177
00178
00179 if (numDOF == 6) {
00180 P = &P6;
00181 K = &K6;
00182 }
00183 else {
00184 P = &P12;
00185 K = &K12;
00186 }
00187
00188
00189 const Vector &end1Crd = end1Ptr->getCrds();
00190 const Vector &end2Crd = end2Ptr->getCrds();
00191 const Vector diff = end1Crd - end2Crd;
00192 double L = diff.Norm();
00193 double v1 = end1Crd.Norm();
00194 double v2 = end2Crd.Norm();
00195 double vm;
00196
00197 vm = (v1<v2) ? v2 : v1;
00198
00199 if (L > LENTOL*vm)
00200 g3ErrorHandler->warning("%s -- Element %d has L=%e, which is greater than the tolerance",
00201 "ZeroLengthSection::setDomain()", this->getTag(), L);
00202
00203
00204 this->DomainComponent::setDomain(theDomain);
00205
00206
00207 this->setTransformation();
00208 }
00209
00210 int
00211 ZeroLengthSection::commitState()
00212 {
00213
00214 return theSection->commitState();
00215 }
00216
00217 int
00218 ZeroLengthSection::revertToLastCommit()
00219 {
00220
00221 return theSection->revertToLastCommit();
00222 }
00223
00224 int
00225 ZeroLengthSection::revertToStart()
00226 {
00227
00228 return theSection->revertToStart();
00229 }
00230
00231 const Matrix &
00232 ZeroLengthSection::getTangentStiff(void)
00233 {
00234
00235 this->computeSectionDefs();
00236
00237
00238 theSection->setTrialSectionDeformation(*v);
00239
00240
00241 const Matrix &kb = theSection->getSectionTangent();
00242
00243
00244 K->addMatrixTripleProduct(0.0, *A, kb, 1.0);
00245
00246 return *K;
00247 }
00248
00249 const Matrix &
00250 ZeroLengthSection::getSecantStiff(void)
00251 {
00252
00253 return this->getTangentStiff();
00254 }
00255
00256 const Matrix &
00257 ZeroLengthSection::getDamp(void)
00258 {
00259
00260 K->Zero();
00261
00262 return *K;
00263 }
00264
00265 const Matrix &
00266 ZeroLengthSection::getMass(void)
00267 {
00268
00269 K->Zero();
00270
00271 return *K;
00272 }
00273
00274 void
00275 ZeroLengthSection::zeroLoad(void)
00276 {
00277
00278 }
00279
00280 int
00281 ZeroLengthSection::addLoad(const Vector &addP)
00282 {
00283
00284 return 0;
00285 }
00286
00287 int
00288 ZeroLengthSection::addInertiaLoadToUnbalance(const Vector &accel)
00289 {
00290
00291 return 0;
00292 }
00293
00294 const Vector &
00295 ZeroLengthSection::getResistingForce()
00296 {
00297
00298 this->computeSectionDefs();
00299
00300
00301 theSection->setTrialSectionDeformation(*v);
00302
00303
00304 const Vector &q = theSection->getStressResultant();
00305
00306
00307 P->addMatrixTransposeVector(0.0, *A, q, 1.0);
00308
00309 return *P;
00310 }
00311
00312 const Vector &
00313 ZeroLengthSection::getResistingForceIncInertia()
00314 {
00315
00316 return this->getResistingForce();
00317 }
00318
00319 int
00320 ZeroLengthSection::sendSelf(int commitTag, Channel &theChannel)
00321 {
00322 int res = 0;
00323
00324
00325
00326
00327 int dataTag = this->getDbTag();
00328
00329
00330
00331 static ID idData(8);
00332
00333 idData(0) = this->getTag();
00334 idData(1) = dimension;
00335 idData(2) = numDOF;
00336 idData(3) = order;
00337 idData(4) = connectedExternalNodes(0);
00338 idData(5) = connectedExternalNodes(1);
00339 idData(6) = theSection->getClassTag();
00340
00341 int secDbTag = theSection->getDbTag();
00342 if (secDbTag == 0) {
00343 secDbTag = theChannel.getDbTag();
00344 if (secDbTag != 0)
00345 theSection->setDbTag(secDbTag);
00346 }
00347 idData(7) = secDbTag;
00348
00349 res += theChannel.sendID(dataTag, commitTag, idData);
00350 if (res < 0) {
00351 g3ErrorHandler->warning("%s -- failed to send ID data",
00352 "ZeroLengthSection::sendSelf");
00353 return res;
00354 }
00355
00356
00357
00358 res += theChannel.sendMatrix(dataTag, commitTag, transformation);
00359 if (res < 0) {
00360 g3ErrorHandler->warning("%s -- failed to send transformation Matrix",
00361 "ZeroLengthSection::sendSelf");
00362 return res;
00363 }
00364
00365
00366 res += theSection->sendSelf(commitTag, theChannel);
00367 if (res < 0) {
00368 g3ErrorHandler->warning("%s -- failed to send Section",
00369 "ZeroLengthSection::sendSelf");
00370 return res;
00371 }
00372
00373 return res;
00374 }
00375
00376 int
00377 ZeroLengthSection::recvSelf(int commitTag, Channel &theChannel, FEM_ObjectBroker &theBroker)
00378 {
00379 int res = 0;
00380
00381 int dataTag = this->getDbTag();
00382
00383
00384
00385
00386 static ID idData(8);
00387
00388 res += theChannel.recvID(dataTag, commitTag, idData);
00389 if (res < 0) {
00390 g3ErrorHandler->warning("%s -- failed to receive ID data",
00391 "ZeroLengthSection::recvSelf");
00392 return res;
00393 }
00394
00395 res += theChannel.recvMatrix(dataTag, commitTag, transformation);
00396 if (res < 0) {
00397 g3ErrorHandler->warning("%s -- failed to receive transformation Matrix",
00398 "ZeroLengthSection::recvSelf");
00399 return res;
00400 }
00401
00402 this->setTag(idData(0));
00403 dimension = idData(1);
00404 numDOF = idData(2);
00405 connectedExternalNodes(0) = idData(4);
00406 connectedExternalNodes(1) = idData(5);
00407
00408
00409 if (order != idData(3)) {
00410
00411 order = idData(3);
00412
00413
00414 if (A != 0)
00415 delete A;
00416
00417 A = new Matrix(order, numDOF);
00418
00419 if (A == 0)
00420 g3ErrorHandler->fatal("%s -- failed to allocate transformation Matrix",
00421 "ZeroLengthSection::recvSelf");
00422
00423
00424 if (v != 0)
00425 delete v;
00426
00427 v = new Vector(order);
00428
00429 if (v == 0)
00430 g3ErrorHandler->fatal("%s -- failed to allocate deformation Vector",
00431 "ZeroLengthSection::recvSelf");
00432
00433 if (numDOF == 6) {
00434 P = &P6;
00435 K = &K6;
00436 }
00437 else {
00438 P = &P12;
00439 K = &K12;
00440 }
00441 }
00442
00443 int secClassTag = idData(6);
00444
00445
00446 if (theSection == 0)
00447 theSection = theBroker.getNewSection(secClassTag);
00448
00449
00450 if (theSection->getClassTag() != secClassTag) {
00451 delete theSection;
00452 theSection = theBroker.getNewSection(secClassTag);
00453 }
00454
00455
00456 if (theSection == 0) {
00457 g3ErrorHandler->warning("%s -- failed to allocate new Section",
00458 "ZeroLengthSection::recvSelf");
00459 return -1;
00460 }
00461
00462
00463 theSection->setDbTag(idData(7));
00464 res += theSection->recvSelf(commitTag, theChannel, theBroker);
00465 if (res < 0) {
00466 g3ErrorHandler->warning("%s -- failed to receive Section",
00467 "ZeroLengthSection::recvSelf");
00468 return res;
00469 }
00470
00471 return res;
00472 }
00473
00474 int
00475 ZeroLengthSection::displaySelf(Renderer &theViewer, int displayMode, float fact)
00476 {
00477
00478 if (end1Ptr == 0 || end2Ptr == 0)
00479 return 0;
00480
00481
00482
00483
00484 const Vector &end1Crd = end1Ptr->getCrds();
00485 const Vector &end2Crd = end2Ptr->getCrds();
00486 const Vector &end1Disp = end1Ptr->getDisp();
00487 const Vector &end2Disp = end2Ptr->getDisp();
00488
00489 if (displayMode == 1 || displayMode == 2) {
00490 static Vector v1(3);
00491 static Vector v2(3);
00492 for (int i = 0; i < dimension; i++) {
00493 v1(i) = end1Crd(i)+end1Disp(i)*fact;
00494 v2(i) = end2Crd(i)+end2Disp(i)*fact;
00495 }
00496
00497 return theViewer.drawLine(v1, v2, 0.0, 0.0);
00498 }
00499
00500 return 0;
00501 }
00502
00503 void
00504 ZeroLengthSection::Print(ostream &s, int flag)
00505 {
00506 s << "ZeroLengthSection, tag: " << this->getTag() << endl;
00507 s << "\tConnected Nodes: " << connectedExternalNodes << endl;
00508 s << "\tSection, tag: " << theSection->getTag() << endl;
00509 }
00510
00511 Response*
00512 ZeroLengthSection::setResponse(char **argv, int argc, Information &eleInformation)
00513 {
00514
00515 if (strcmp(argv[0],"force") == 0 || strcmp(argv[0],"forces") == 0)
00516 return new ElementResponse(this, 1, *P);
00517
00518
00519 else if (strcmp(argv[0],"stiff") == 0 || strcmp(argv[0],"stiffness") == 0)
00520 return new ElementResponse(this, 2, *K);
00521
00522 else if (strcmp(argv[0],"defo") == 0 || strcmp(argv[0],"deformations") == 0 ||
00523 strcmp(argv[0],"deformation") == 0) {
00524 return new ElementResponse(this, 3, Vector(order));
00525 }
00526
00527 else if (strcmp(argv[0],"section") == 0)
00528 return theSection->setResponse(&argv[1], argc-1, eleInformation);
00529
00530 else
00531 return 0;
00532 }
00533
00534 int
00535 ZeroLengthSection::getResponse(int responseID, Information &eleInfo)
00536 {
00537 switch (responseID) {
00538 case 1:
00539 return eleInfo.setVector(this->getResistingForce());
00540
00541 case 2:
00542 return eleInfo.setMatrix(this->getTangentStiff());
00543
00544 case 3:
00545 this->computeSectionDefs();
00546 return eleInfo.setVector(*v);
00547
00548 default:
00549 return -1;
00550 }
00551 }
00552
00553
00554
00555
00556
00557
00558 void
00559 ZeroLengthSection::setUp(int Nd1, int Nd2, const Vector &x, const Vector &yp)
00560 {
00561
00562 if (connectedExternalNodes.Size() != 2)
00563 g3ErrorHandler->fatal("%s -- failed to create an ID of correct size",
00564 "ZeroLengthSection::setUp");
00565
00566 connectedExternalNodes(0) = Nd1;
00567 connectedExternalNodes(1) = Nd2;
00568
00569
00570 if ( x.Size() != 3 || yp.Size() != 3 )
00571 g3ErrorHandler->fatal("%s -- incorrect dimension of orientation vectors",
00572 "ZeroLengthSection::setUp");
00573
00574
00575
00576 static Vector z(3);
00577 z(0) = x(1)*yp(2) - x(2)*yp(1);
00578 z(1) = x(2)*yp(0) - x(0)*yp(2);
00579 z(2) = x(0)*yp(1) - x(1)*yp(0);
00580
00581
00582 static Vector y(3);
00583 y(0) = z(1)*x(2) - z(2)*x(1);
00584 y(1) = z(2)*x(0) - z(0)*x(2);
00585 y(2) = z(0)*x(1) - z(1)*x(0);
00586
00587
00588 double xn = x.Norm();
00589 double yn = y.Norm();
00590 double zn = z.Norm();
00591
00592
00593 if (xn == 0 || yn == 0 || zn == 0)
00594 g3ErrorHandler->fatal("%s -- invalid vectors to constructor",
00595 "ZeroLengthSection::setUp");
00596
00597
00598 for (int i = 0; i < 3; i++) {
00599 transformation(0,i) = x(i)/xn;
00600 transformation(1,i) = y(i)/yn;
00601 transformation(2,i) = z(i)/zn;
00602 }
00603 }
00604
00605
00606 void
00607 ZeroLengthSection::setTransformation(void)
00608 {
00609
00610 if (A != 0)
00611 delete A;
00612
00613 A = new Matrix(order, numDOF);
00614
00615 if (A == 0)
00616 g3ErrorHandler->fatal("%s -- failed to allocate transformation Matrix",
00617 "ZeroLengthSection::setTransformation");
00618
00619
00620 if (v != 0)
00621 delete v;
00622
00623 v = new Vector(order);
00624
00625
00626 const ID &code = theSection->getType();
00627
00628
00629 Matrix &tran = *A;
00630
00631 tran.Zero();
00632
00633
00634 for (int i = 0; i < order; i++) {
00635
00636
00637 switch(code(i)) {
00638
00639
00640 case SECTION_RESPONSE_MZ:
00641 if (numDOF == 6) {
00642 tran(i,3) = 0.0;
00643 tran(i,4) = 0.0;
00644 tran(i,5) = transformation(2,2);
00645 }
00646 else if (numDOF == 12) {
00647 tran(i,9) = transformation(2,0);
00648 tran(i,10) = transformation(2,1);
00649 tran(i,11) = transformation(2,2);
00650 }
00651 break;
00652 case SECTION_RESPONSE_P:
00653 if (numDOF == 6) {
00654 tran(i,3) = transformation(0,0);
00655 tran(i,4) = transformation(0,1);
00656 tran(i,5) = 0.0;
00657 }
00658 else if (numDOF == 12) {
00659 tran(i,6) = transformation(0,0);
00660 tran(i,7) = transformation(0,1);
00661 tran(i,8) = transformation(0,2);
00662 }
00663 break;
00664 case SECTION_RESPONSE_VY:
00665 if (numDOF == 6) {
00666 tran(i,3) = transformation(1,0);
00667 tran(i,4) = transformation(1,1);
00668 tran(i,5) = 0.0;
00669 }
00670 else if (numDOF == 12) {
00671 tran(i,6) = transformation(1,0);
00672 tran(i,7) = transformation(1,1);
00673 tran(i,8) = transformation(1,2);
00674 }
00675 break;
00676
00677
00678 case SECTION_RESPONSE_MY:
00679 if (numDOF == 12) {
00680 tran(i,9) = transformation(1,0);
00681 tran(i,10) = transformation(1,1);
00682 tran(i,11) = transformation(1,2);
00683 }
00684 break;
00685 case SECTION_RESPONSE_VZ:
00686 if (numDOF == 12) {
00687 tran(i,6) = transformation(2,0);
00688 tran(i,7) = transformation(2,1);
00689 tran(i,8) = transformation(2,2);
00690 }
00691 break;
00692 case SECTION_RESPONSE_T:
00693 if (numDOF == 12) {
00694 tran(i,9) = transformation(0,0);
00695 tran(i,10) = transformation(0,1);
00696 tran(i,11) = transformation(0,2);
00697 }
00698 break;
00699 default:
00700 break;
00701 }
00702
00703
00704 for (int j = 0; j < numDOF/2; j++ )
00705 tran(i,j) = -tran(i,j+numDOF/2);
00706 }
00707 }
00708
00709 void
00710 ZeroLengthSection::computeSectionDefs(void)
00711 {
00712
00713 const Vector &u1 = end1Ptr->getTrialDisp();
00714 const Vector &u2 = end2Ptr->getTrialDisp();
00715
00716
00717 const Vector diff = u2 - u1;
00718
00719
00720 Vector &def = *v;
00721 const Matrix &tran = *A;
00722
00723 def.Zero();
00724
00725
00726 for (int i = 0; i < order; i++)
00727 for (int j = 0; j < numDOF/2; j++)
00728 def(i) += -diff(j)*tran(i,j);
00729 }