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