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