CorotTruss.cpp

Go to the documentation of this file.
00001 /* ****************************************************************** **
00002 **    OpenSees - Open System for Earthquake Engineering Simulation    **
00003 **          Pacific Earthquake Engineering Research Center            **
00004 **                                                                    **
00005 **                                                                    **
00006 ** (C) Copyright 1999, The Regents of the University of California    **
00007 ** All Rights Reserved.                                               **
00008 **                                                                    **
00009 ** Commercial use of this program without express permission of the   **
00010 ** University of California, Berkeley, is strictly prohibited.  See   **
00011 ** file 'COPYRIGHT'  in main directory for information on usage and   **
00012 ** redistribution,  and for a DISCLAIMER OF ALL WARRANTIES.           **
00013 **                                                                    **
00014 ** Developed by:                                                      **
00015 **   Frank McKenna (fmckenna@ce.berkeley.edu)                         **
00016 **   Gregory L. Fenves (fenves@ce.berkeley.edu)                       **
00017 **   Filip C. Filippou (filippou@ce.berkeley.edu)                     **
00018 **                                                                    **
00019 ** ****************************************************************** */
00020                                                                         
00021 // $Revision: 1.12 $
00022 // $Date: 2006/08/04 19:13:02 $
00023 // $Source: /usr/local/cvs/OpenSees/SRC/element/truss/CorotTruss.cpp,v $
00024                                                                         
00025 // Written: MHS 
00026 // Created: May 2001
00027 //
00028 // Description: This file contains the class implementation for CorotTruss.
00029 
00030 #include <CorotTruss.h>
00031 #include <Information.h>
00032 
00033 #include <Domain.h>
00034 #include <Node.h>
00035 #include <Channel.h>
00036 #include <FEM_ObjectBroker.h>
00037 #include <UniaxialMaterial.h>
00038 #include <Renderer.h>
00039 
00040 #include <math.h>
00041 #include <stdlib.h>
00042 #include <string.h>
00043 
00044 #include <ElementResponse.h>
00045 
00046 Matrix CorotTruss::M2(2,2);
00047 Matrix CorotTruss::M4(4,4);
00048 Matrix CorotTruss::M6(6,6);
00049 Matrix CorotTruss::M12(12,12);
00050 
00051 Vector CorotTruss::V2(2);
00052 Vector CorotTruss::V4(4);
00053 Vector CorotTruss::V6(6);
00054 Vector CorotTruss::V12(12);
00055 
00056 // constructor:
00057 //  responsible for allocating the necessary space needed by each object
00058 //  and storing the tags of the CorotTruss end nodes.
00059 CorotTruss::CorotTruss(int tag, int dim,
00060                            int Nd1, int Nd2, 
00061                            UniaxialMaterial &theMat,
00062                            double a, double r)
00063   :Element(tag,ELE_TAG_CorotTruss),     
00064   theMaterial(0), connectedExternalNodes(2),
00065   numDOF(0), numDIM(dim),
00066   Lo(0.0), Ln(0.0), 
00067   A(a), rho(r), R(3,3),
00068   theMatrix(0), theVector(0)
00069 {
00070   // get a copy of the material and check we obtained a valid copy
00071   theMaterial = theMat.getCopy();
00072   if (theMaterial == 0) {
00073     opserr << "FATAL CorotTruss::CorotTruss - " <<  tag <<
00074       "failed to get a copy of material with tag " << theMat.getTag() << endln;
00075     exit(-1);
00076   }
00077   
00078   // ensure the connectedExternalNode ID is of correct size & set values
00079   if (connectedExternalNodes.Size() != 2) {
00080     opserr << "FATAL CorotTruss::CorotTruss - " <<  tag <<
00081       "failed to create an ID of size 2\n";
00082     exit(-1);
00083   }
00084   
00085   connectedExternalNodes(0) = Nd1;
00086   connectedExternalNodes(1) = Nd2;        
00087 
00088   // set node pointers to NULL
00089   theNodes[0] = 0;
00090   theNodes[1] = 0;
00091 }
00092 
00093 // constructor:
00094 //   invoked by a FEM_ObjectBroker - blank object that recvSelf needs
00095 //   to be invoked upon
00096 CorotTruss::CorotTruss()
00097   :Element(0,ELE_TAG_CorotTruss),     
00098   theMaterial(0),connectedExternalNodes(2),
00099   numDOF(0), numDIM(0),
00100   Lo(0.0), Ln(0.0), 
00101   A(0.0), rho(0.0), R(3,3),
00102   theMatrix(0), theVector(0)
00103 {
00104   // ensure the connectedExternalNode ID is of correct size 
00105   if (connectedExternalNodes.Size() != 2) {
00106     opserr << "FATAL CorotTruss::CorotTruss - failed to create an ID of size 2\n";
00107     exit(-1);
00108   }
00109 
00110   // set node pointers to NULL
00111   theNodes[0] = 0;
00112   theNodes[1] = 0;
00113 }
00114 
00115 //  destructor
00116 //     delete must be invoked on any objects created by the object
00117 //     and on the matertial object.
00118 CorotTruss::~CorotTruss()
00119 {
00120   // invoke the destructor on any objects created by the object
00121   // that the object still holds a pointer to
00122   if (theMaterial != 0)
00123     delete theMaterial;
00124 }
00125 
00126 int
00127 CorotTruss::getNumExternalNodes(void) const
00128 {
00129     return 2;
00130 }
00131 
00132 const ID &
00133 CorotTruss::getExternalNodes(void) 
00134 {
00135         return connectedExternalNodes;
00136 }
00137 
00138 Node **
00139 CorotTruss::getNodePtrs(void) 
00140 {
00141   return theNodes;
00142 }
00143 
00144 int
00145 CorotTruss::getNumDOF(void) 
00146 {
00147         return numDOF;
00148 }
00149 
00150 // method: setDomain()
00151 //    to set a link to the enclosing Domain and to set the node pointers.
00152 //    also determines the number of dof associated
00153 //    with the CorotTruss element, we set matrix and vector pointers,
00154 //    allocate space for t matrix, determine the length
00155 //    and set the transformation matrix.
00156 void
00157 CorotTruss::setDomain(Domain *theDomain)
00158 {
00159   // check Domain is not null - invoked when object removed from a domain
00160   if (theDomain == 0) {
00161     theNodes[0] = 0;
00162     theNodes[1] = 0;
00163     Lo = 0.0;
00164     Ln = 0.0;
00165     return;
00166   }
00167   
00168   // first set the node pointers
00169   int Nd1 = connectedExternalNodes(0);
00170   int Nd2 = connectedExternalNodes(1);
00171   theNodes[0] = theDomain->getNode(Nd1);
00172   theNodes[1] = theDomain->getNode(Nd2);        
00173   
00174   // if can't find both - send a warning message
00175   if ((theNodes[0] == 0) || (theNodes[1] == 0)) {
00176     opserr << "CorotTruss::setDomain() - CorotTruss " << this->getTag() << " node " <<
00177       Nd1 << "does not exist in the model \n";
00178     
00179     // fill this in so don't segment fault later
00180     numDOF = 6;    
00181     
00182     return;
00183   }
00184   
00185   // now determine the number of dof and the dimesnion    
00186   int dofNd1 = theNodes[0]->getNumberDOF();
00187   int dofNd2 = theNodes[1]->getNumberDOF();     
00188   
00189   // if differing dof at the ends - print a warning message
00190   if (dofNd1 != dofNd2) {
00191     opserr << "WARNING CorotTruss::setDomain(): nodes " << Nd1 <<
00192       " and " << Nd2 << "have differing dof at ends for CorotTruss " << this->getTag() << endln;
00193     
00194     // fill this in so don't segment fault later
00195     numDOF = 6;    
00196     
00197     return;
00198   }     
00199   
00200   if (numDIM == 1 && dofNd1 == 1) {
00201     numDOF = 2;
00202     theMatrix = &M2;
00203     theVector = &V2;
00204   }
00205   else if (numDIM == 2 && dofNd1 == 2) {
00206     numDOF = 4;
00207     theMatrix = &M4;
00208     theVector = &V4;
00209   }
00210   else if (numDIM == 2 && dofNd1 == 3) {
00211     numDOF = 6;
00212     theMatrix = &M6;
00213     theVector = &V6;
00214   }
00215   else if (numDIM == 3 && dofNd1 == 3) {
00216     numDOF = 6;
00217     theMatrix = &M6;
00218     theVector = &V6;
00219   }
00220   else if (numDIM == 3 && dofNd1 == 6) {
00221     numDOF = 12;
00222     theMatrix = &M12;
00223     theVector = &V12;
00224   }
00225   else {
00226     opserr << " CorotTruss::setDomain -- nodal DOF " << dofNd1 << " not compatible with element\n";
00227     
00228     // fill this in so don't segment fault later
00229     numDOF = 6;    
00230     
00231     return;
00232   }
00233 
00234         // call the base class method
00235         this->DomainComponent::setDomain(theDomain);
00236 
00237         // now determine the length, cosines and fill in the transformation
00238         // NOTE t = -t(every one else uses for residual calc)
00239         const Vector &end1Crd = theNodes[0]->getCrds();
00240         const Vector &end2Crd = theNodes[1]->getCrds();
00241 
00242         // Determine global offsets
00243     double cosX[3];
00244     cosX[0] = 0.0;  cosX[1] = 0.0;  cosX[2] = 0.0;
00245     int i;
00246     for (i = 0; i < numDIM; i++) {
00247         cosX[i] += end2Crd(i)-end1Crd(i);
00248     }
00249 
00250         // Set undeformed and initial length
00251         Lo = cosX[0]*cosX[0] + cosX[1]*cosX[1] + cosX[2]*cosX[2];
00252         Lo = sqrt(Lo);
00253         Ln = Lo;
00254 
00255     // Initial offsets
00256         d21[0] = Lo;
00257         d21[1] = 0.0;
00258         d21[2] = 0.0;
00259 
00260         // Set global orientation
00261         cosX[0] /= Lo;
00262         cosX[1] /= Lo;
00263         cosX[2] /= Lo;
00264 
00265         R(0,0) = cosX[0];
00266         R(0,1) = cosX[1];
00267         R(0,2) = cosX[2];
00268 
00269         // Element lies outside the YZ plane
00270         if (fabs(cosX[0]) > 0.0) {
00271                 R(1,0) = -cosX[1];
00272                 R(1,1) =  cosX[0];
00273                 R(1,2) =  0.0;
00274 
00275                 R(2,0) = -cosX[0]*cosX[2];
00276                 R(2,1) = -cosX[1]*cosX[2];
00277                 R(2,2) =  cosX[0]*cosX[0] + cosX[1]*cosX[1];
00278         }
00279         // Element is in the YZ plane
00280         else {
00281                 R(1,0) =  0.0;
00282                 R(1,1) = -cosX[2];
00283                 R(1,2) =  cosX[1];
00284 
00285                 R(2,0) =  1.0;
00286                 R(2,1) =  0.0;
00287                 R(2,2) =  0.0;
00288         }
00289 
00290         // Orthonormalize last two rows of R
00291         double norm;
00292         for (i = 1; i < 3; i++) {
00293                 norm = sqrt(R(i,0)*R(i,0) + R(i,1)*R(i,1) + R(i,2)*R(i,2));
00294                 R(i,0) /= norm;
00295                 R(i,1) /= norm;
00296                 R(i,2) /= norm;
00297         }
00298 }
00299 
00300 int
00301 CorotTruss::commitState()
00302 {
00303   int retVal = 0;
00304   // call element commitState to do any base class stuff
00305   if ((retVal = this->Element::commitState()) != 0) {
00306     opserr << "CorotTruss::commitState () - failed in base class\n";
00307   }    
00308   retVal = theMaterial->commitState();
00309   return retVal;
00310 }
00311 
00312 int
00313 CorotTruss::revertToLastCommit()
00314 {
00315         // Revert the material
00316         return theMaterial->revertToLastCommit();
00317 }
00318 
00319 int
00320 CorotTruss::revertToStart()
00321 {
00322         // Revert the material to start
00323         return theMaterial->revertToStart();
00324 }
00325 
00326 int
00327 CorotTruss::update(void)
00328 {
00329   // Nodal displacements
00330   const Vector &end1Disp = theNodes[0]->getTrialDisp();
00331   const Vector &end2Disp = theNodes[1]->getTrialDisp();    
00332   
00333   // Initial offsets
00334   d21[0] = Lo;
00335   d21[1] = 0.0;
00336   d21[2] = 0.0;
00337   
00338   // Update offsets in basic system due to nodal displacements
00339   for (int i = 0; i < numDIM; i++) {
00340     d21[0] += R(0,i)*(end2Disp(i)-end1Disp(i));
00341     d21[1] += R(1,i)*(end2Disp(i)-end1Disp(i));
00342     d21[2] += R(2,i)*(end2Disp(i)-end1Disp(i));
00343   }
00344   
00345   // Compute new length
00346   Ln = d21[0]*d21[0] + d21[1]*d21[1] + d21[2]*d21[2];
00347   Ln = sqrt(Ln);
00348   
00349   // Compute engineering strain
00350   double strain = (Ln-Lo)/Lo;
00351   
00352   // Set material trial strain
00353   return theMaterial->setTrialStrain(strain);
00354 }
00355 
00356 const Matrix &
00357 CorotTruss::getTangentStiff(void)
00358 {
00359     static Matrix kl(3,3);
00360 
00361     // Material stiffness
00362     //
00363     // Get material tangent
00364     double EA = A*theMaterial->getTangent();
00365     EA /= (Ln * Ln * Lo);
00366 
00367     int i,j;
00368     for (i = 0; i < 3; i++)
00369         for (j = 0; j < 3; j++)
00370             kl(i,j) = EA*d21[i]*d21[j];
00371 
00372     // Geometric stiffness
00373     //
00374     // Get material stress
00375     double q = A*theMaterial->getStress();
00376     double SA = q/(Ln*Ln*Ln);
00377     double SL = q/Ln;
00378     
00379     for (i = 0; i < 3; i++) {
00380         kl(i,i) += SL;
00381         for (j = 0; j < 3; j++)
00382             kl(i,j) -= SA*d21[i]*d21[j];
00383     }
00384     
00385     // Compute R'*kl*R
00386     static Matrix kg(3,3);
00387     kg.addMatrixTripleProduct(0.0, R, kl, 1.0);
00388 
00389     Matrix &K = *theMatrix;
00390     K.Zero();
00391 
00392     // Copy stiffness into appropriate blocks in element stiffness
00393     int numDOF2 = numDOF/2;
00394     for (i = 0; i < numDIM; i++) {
00395         for (j = 0; j < numDIM; j++) {
00396             K(i,j)                 =  kg(i,j);
00397             K(i,j+numDOF2)         = -kg(i,j);
00398             K(i+numDOF2,j)         = -kg(i,j);
00399             K(i+numDOF2,j+numDOF2) =  kg(i,j);
00400         }
00401     }
00402 
00403     return *theMatrix;
00404 }
00405 
00406 const Matrix &
00407 CorotTruss::getInitialStiff(void)
00408 {
00409     static Matrix kl(3,3);
00410 
00411     // Material stiffness
00412     kl.Zero();
00413     kl(0,0) = A * theMaterial->getInitialTangent() / Lo;
00414 
00415     // Compute R'*kl*R
00416     static Matrix kg(3,3);
00417     kg.addMatrixTripleProduct(0.0, R, kl, 1.0);
00418 
00419     Matrix &K = *theMatrix;
00420     K.Zero();
00421 
00422     // Copy stiffness into appropriate blocks in element stiffness
00423     int numDOF2 = numDOF/2;
00424     for (int i = 0; i < numDIM; i++) {
00425         for (int j = 0; j < numDIM; j++) {
00426             K(i,j)                 =  kg(i,j);
00427             K(i,j+numDOF2)         = -kg(i,j);
00428             K(i+numDOF2,j)         = -kg(i,j);
00429             K(i+numDOF2,j+numDOF2) =  kg(i,j);
00430         }
00431     }
00432 
00433     return *theMatrix;
00434 }
00435 
00436 
00437 const Matrix &
00438 CorotTruss::getMass(void)
00439 {
00440     Matrix &Mass = *theMatrix;
00441     Mass.Zero();
00442 
00443     // check for quick return
00444     if (Lo == 0.0 || rho == 0.0)
00445         return Mass;
00446 
00447     double M = 0.5*rho*Lo;
00448     int numDOF2 = numDOF/2;
00449     for (int i = 0; i < numDIM; i++) {
00450         Mass(i,i)                 = M;
00451         Mass(i+numDOF2,i+numDOF2) = M;
00452     }
00453 
00454     return *theMatrix;
00455 }
00456 
00457 void 
00458 CorotTruss::zeroLoad(void)
00459 {
00460         return;
00461 }
00462 
00463 int 
00464 CorotTruss::addLoad(ElementalLoad *theLoad, double loadFactor)
00465 {
00466   opserr << "CorotTruss::addLoad - load type unknown for truss with tag: " << this->getTag() << endln;
00467   
00468   return -1;
00469 }
00470 
00471 
00472 
00473 int 
00474 CorotTruss::addInertiaLoadToUnbalance(const Vector &accel)
00475 {
00476         return 0;
00477 }
00478 
00479 const Vector &
00480 CorotTruss::getResistingForce()
00481 {
00482         // Get material stress
00483         double SA = A*theMaterial->getStress();
00484         SA /= Ln;
00485 
00486     static Vector ql(3);
00487 
00488         ql(0) = d21[0]*SA;
00489         ql(1) = d21[1]*SA;
00490         ql(2) = d21[2]*SA;
00491 
00492     static Vector qg(3);
00493     qg.addMatrixTransposeVector(0.0, R, ql, 1.0);
00494 
00495     Vector &P = *theVector;
00496     P.Zero();
00497 
00498     // Copy forces into appropriate places
00499     int numDOF2 = numDOF/2;
00500     for (int i = 0; i < numDIM; i++) {
00501         P(i)         = -qg(i);
00502         P(i+numDOF2) =  qg(i);
00503     }
00504 
00505     return *theVector;
00506 }
00507 
00508 
00509 
00510 const Vector &
00511 CorotTruss::getResistingForceIncInertia()
00512 {       
00513     Vector &P = *theVector;
00514     P = this->getResistingForce();
00515     
00516     if (rho != 0.0) {
00517         
00518       const Vector &accel1 = theNodes[0]->getTrialAccel();
00519       const Vector &accel2 = theNodes[1]->getTrialAccel();      
00520       
00521       double M = 0.5*rho*Lo;
00522       int numDOF2 = numDOF/2;
00523       for (int i = 0; i < numDIM; i++) {
00524         P(i)        += M*accel1(i);
00525         P(i+numDOF2) += M*accel2(i);
00526       }
00527     }
00528 
00529     // add the damping forces if rayleigh damping
00530     if (alphaM != 0.0 || betaK != 0.0 || betaK0 != 0.0 || betaKc != 0.0)
00531       *theVector += this->getRayleighDampingForces();
00532 
00533     return *theVector;
00534 }
00535 
00536 int
00537 CorotTruss::sendSelf(int commitTag, Channel &theChannel)
00538 {
00539   int res;
00540 
00541   // note: we don't check for dataTag == 0 for Element
00542   // objects as that is taken care of in a commit by the Domain
00543   // object - don't want to have to do the check if sending data
00544   int dataTag = this->getDbTag();
00545 
00546   // truss packs it's data into a Vector and sends this to theChannel
00547   // along with it's dbTag and the commitTag passed in the arguments
00548 
00549   static Vector data(7);
00550   data(0) = this->getTag();
00551   data(1) = numDIM;
00552   data(2) = numDOF;
00553   data(3) = A;
00554   data(6) = rho;
00555   
00556   data(4) = theMaterial->getClassTag();
00557   int matDbTag = theMaterial->getDbTag();
00558 
00559   // NOTE: we do have to ensure that the material has a database
00560   // tag if we are sending to a database channel.
00561   if (matDbTag == 0) {
00562     matDbTag = theChannel.getDbTag();
00563     if (matDbTag != 0)
00564       theMaterial->setDbTag(matDbTag);
00565   }
00566   data(5) = matDbTag;
00567 
00568   res = theChannel.sendVector(dataTag, commitTag, data);
00569   if (res < 0) {
00570     opserr << "WARNING Truss::sendSelf() - " << this->getTag() << " failed to send Vector\n";
00571     return -1;
00572   }           
00573 
00574   // truss then sends the tags of it's two end nodes
00575 
00576   res = theChannel.sendID(dataTag, commitTag, connectedExternalNodes);
00577   if (res < 0) {
00578     opserr << "WARNING Truss::sendSelf() - " << this->getTag() << " failed to send Vector\n";
00579     return -2;
00580   }
00581 
00582   // finally truss asks it's material object to send itself
00583   res = theMaterial->sendSelf(commitTag, theChannel);
00584   if (res < 0) {
00585     opserr << "WARNING Truss::sendSelf() - " << this->getTag() << " failed to send its Material\n";
00586     return -3;
00587   }
00588 
00589   return 0;
00590 }
00591 
00592 int
00593 CorotTruss::recvSelf(int commitTag, Channel &theChannel, FEM_ObjectBroker &theBroker)
00594 {
00595   int res;
00596   int dataTag = this->getDbTag();
00597 
00598   // truss creates a Vector, receives the Vector and then sets the 
00599   // internal data with the data in the Vector
00600 
00601   static Vector data(7);
00602   res = theChannel.recvVector(dataTag, commitTag, data);
00603   if (res < 0) {
00604     opserr << "WARNING Truss::recvSelf() - failed to receive Vector\n";
00605     return -1;
00606   }           
00607 
00608   this->setTag((int)data(0));
00609   numDIM = (int)data(1);
00610   numDOF = (int)data(2);
00611   A = data(3);
00612   rho = data(6);
00613   
00614   // truss now receives the tags of it's two external nodes
00615   res = theChannel.recvID(dataTag, commitTag, connectedExternalNodes);
00616   if (res < 0) {
00617     opserr << "WARNING Truss::recvSelf() - " << this->getTag() << " failed to receive ID\n";
00618     return -2;
00619   }
00620 
00621   // finally truss creates a material object of the correct type,
00622   // sets its database tag and asks this new object to recveive itself.
00623 
00624   int matClass = (int)data(4);
00625   int matDb = (int)data(5);
00626 
00627   // check if we have a material object already & if we do if of right type
00628   if ((theMaterial == 0) || (theMaterial->getClassTag() != matClass)) {
00629 
00630     // if old one .. delete it
00631     if (theMaterial != 0)
00632       delete theMaterial;
00633 
00634     // create a new material object
00635     theMaterial = theBroker.getNewUniaxialMaterial(matClass);
00636     if (theMaterial == 0) {
00637       opserr << "WARNING Truss::recvSelf() - " << this->getTag() << 
00638         "failed to get a blank Material of type: " << matClass << endln;
00639       return -3;
00640     }
00641   }
00642 
00643   theMaterial->setDbTag(matDb); // note: we set the dbTag before we receive the material
00644   res = theMaterial->recvSelf(commitTag, theChannel, theBroker);
00645   if (res < 0) {
00646     opserr << "WARNING Truss::recvSelf() - " << this->getTag() << " failed to receive its Material\n";
00647     return -3;    
00648   }
00649 
00650   return 0;
00651 }
00652 
00653 int
00654 CorotTruss::displaySelf(Renderer &theViewer, int displayMode, float fact)
00655 {
00656         // ensure setDomain() worked
00657         if (Ln == 0.0)
00658                 return 0;
00659 
00660         // first determine the two end points of the CorotTruss based on
00661         // the display factor (a measure of the distorted image)
00662         // store this information in 2 3d vectors v1 and v2
00663         const Vector &end1Crd = theNodes[0]->getCrds();
00664         const Vector &end2Crd = theNodes[1]->getCrds(); 
00665         const Vector &end1Disp = theNodes[0]->getDisp();
00666         const Vector &end2Disp = theNodes[1]->getDisp();    
00667 
00668         static Vector v1(3);
00669         static Vector v2(3);
00670         for (int i = 0; i < numDIM; i++) {
00671                 v1(i) = end1Crd(i)+end1Disp(i)*fact;
00672                 v2(i) = end2Crd(i)+end2Disp(i)*fact;    
00673         }
00674 
00675         return theViewer.drawLine(v1, v2, 1.0, 1.0);
00676 }
00677 
00678 void
00679 CorotTruss::Print(OPS_Stream &s, int flag)
00680 {
00681         s << "\nCorotTruss, tag: " << this->getTag() << endln;
00682         s << "\tConnected Nodes: " << connectedExternalNodes;
00683         s << "\tSection Area: " << A << endln;
00684         s << "\tUndeformed Length: " << Lo << endln;
00685         s << "\tCurrent Length: " << Ln << endln;
00686         s << "\tMass Density/Length: " << rho << endln;
00687         s << "\tRotation matrix: " << endln;
00688 
00689         if (theMaterial) {
00690                 s << "\tAxial Force: " << A*theMaterial->getStress() << endln;
00691                 s << "\tUniaxialMaterial, tag: " << theMaterial->getTag() << endln;
00692                 theMaterial->Print(s,flag);
00693         }
00694 }
00695 
00696 Response*
00697 CorotTruss::setResponse(const char **argv, int argc, Information &eleInfo, OPS_Stream &output)
00698 {
00699   Response *theResponse = 0;
00700 
00701   output.tag("ElementOutput");
00702   output.attr("eleType","Truss");
00703   output.attr("eleTag",this->getTag());
00704   output.attr("node1",connectedExternalNodes[0]);
00705   output.attr("node2",connectedExternalNodes[1]);
00706 
00707   //
00708   // we compare argv[0] for known response types for the Truss
00709   //
00710 
00711   if (strcmp(argv[0],"force") == 0 || strcmp(argv[0],"forces") == 0 || strcmp(argv[0],"axialForce") == 0) {
00712 
00713     output.tag("ResponseType", "N");
00714     theResponse =  new ElementResponse(this, 1, 0.0);
00715 
00716   } else if (strcmp(argv[0],"defo") == 0 || strcmp(argv[0],"deformations") == 0 ||
00717              strcmp(argv[0],"deformation") == 0) {
00718 
00719     output.tag("ResponseType", "eps");
00720     theResponse = new ElementResponse(this, 2, 0.0);
00721 
00722   // a material quantity    
00723   } else if (strcmp(argv[0],"material") == 0 || strcmp(argv[0],"-material") == 0) {
00724 
00725     theResponse =  theMaterial->setResponse(&argv[1], argc-1, eleInfo, output);
00726   }
00727 
00728   output.endTag();
00729   return theResponse;
00730 }
00731 
00732 int 
00733 CorotTruss::getResponse(int responseID, Information &eleInfo)
00734 {
00735   switch (responseID) {
00736     case 1:
00737           return eleInfo.setDouble(A * theMaterial->getStress());
00738       
00739     case 2:
00740           return eleInfo.setDouble(Lo * theMaterial->getStrain());
00741       
00742     default:
00743           return 0;
00744   }
00745 }

Generated on Mon Oct 23 15:05:09 2006 for OpenSees by doxygen 1.5.0