Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

ElasticBeam2d.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.4 $
00022 // $Date: 2001/06/14 05:59:35 $
00023 // $Source: /usr/local/cvs/OpenSees/SRC/element/beam2d/ElasticBeam2d.cpp,v $
00024                                                                         
00025                                                                         
00026 // File: ~/model/ElasticBeam2d.C
00027 //
00028 // Written: fmk 11/95
00029 // Revised:
00030 //
00031 // Purpose: This file contains the class definition for ElasticBeam2d.
00032 // ElasticBeam2d is a 3d beam element. As such it can only
00033 // connect to a node with 6-dof. 
00034 
00035 #include <ElasticBeam2d.h>
00036 #include <Domain.h>
00037 #include <Channel.h>
00038 #include <FEM_ObjectBroker.h>
00039 
00040 #include <CrdTransf2d.h>
00041 #include <Information.h>
00042 #include <ElementResponse.h>
00043 #include <Renderer.h>
00044 
00045 #include <math.h>
00046 #include <stdlib.h>
00047 
00048 Matrix ElasticBeam2d::K(6,6);
00049 Vector ElasticBeam2d::P(6);
00050 Matrix ElasticBeam2d::kb(3,3);
00051 
00052 ElasticBeam2d::ElasticBeam2d()
00053 :Element(0,ELE_TAG_ElasticBeam2d), 
00054   A(0), E(0), I(0), L(0.0), rho(0.0), Q(6), q(3),
00055   connectedExternalNodes(2), theCoordTransf(0)
00056 {
00057     // does nothing
00058 }
00059 
00060 ElasticBeam2d::ElasticBeam2d(int tag, double a, double e, double i, 
00061        int Nd1, int Nd2, 
00062        CrdTransf2d &coordTransf, double r)
00063 :Element(tag,ELE_TAG_ElasticBeam2d), 
00064   A(a), E(e), I(i), L(0.0), rho(r), Q(6), q(3),
00065   connectedExternalNodes(2), theCoordTransf(0)
00066 {
00067     connectedExternalNodes(0) = Nd1;
00068     connectedExternalNodes(1) = Nd2;
00069     
00070     theCoordTransf = coordTransf.getCopy();
00071     
00072     if (!theCoordTransf)
00073  g3ErrorHandler->fatal("ElasticBeam2d::ElasticBeam2d -- failed to get copy of coordinate transformation");
00074 }
00075 
00076 ElasticBeam2d::~ElasticBeam2d()
00077 {
00078     if (theCoordTransf)
00079  delete theCoordTransf;
00080 }
00081 
00082 int
00083 ElasticBeam2d::getNumExternalNodes(void) const
00084 {
00085     return 2;
00086 }
00087 
00088 const ID &
00089 ElasticBeam2d::getExternalNodes(void) 
00090 {
00091     return connectedExternalNodes;
00092 }
00093 
00094 int
00095 ElasticBeam2d::getNumDOF(void)
00096 {
00097     return 6;
00098 }
00099 
00100 void
00101 ElasticBeam2d::setDomain(Domain *theDomain)
00102 {
00103     if (theDomain == 0)
00104  g3ErrorHandler->fatal("ElasticBeam2d::setDomain -- Domain is null");
00105     
00106     node1Ptr = theDomain->getNode(connectedExternalNodes(0));
00107     node2Ptr = theDomain->getNode(connectedExternalNodes(1));    
00108     
00109     if (node1Ptr == 0)
00110  g3ErrorHandler->fatal("ElasticBeam2d::setDomain -- Node 1: %i does not exist",
00111          connectedExternalNodes(0));
00112     
00113     if (node2Ptr == 0)
00114  g3ErrorHandler->fatal("ElasticBeam2d::setDomain -- Node 2: %i does not exist",
00115          connectedExternalNodes(1));
00116  
00117     int dofNd1 = node1Ptr->getNumberDOF();
00118     int dofNd2 = node2Ptr->getNumberDOF();    
00119     
00120     if (dofNd1 != 3)
00121  g3ErrorHandler->fatal("ElasticBeam2d::setDomain -- Node 1: %i has incorrect number of DOF",
00122          connectedExternalNodes(0));
00123     
00124     if (dofNd2 != 3)
00125  g3ErrorHandler->fatal("ElasticBeam2d::setDomain -- Node 2: %i has incorrect number of DOF",
00126          connectedExternalNodes(1)); 
00127  
00128     this->DomainComponent::setDomain(theDomain);
00129     
00130     if (theCoordTransf->initialize(node1Ptr, node2Ptr) != 0)
00131  g3ErrorHandler->fatal("ElasticBeam2d::setDomain -- Error initializing coordinate transformation");
00132     
00133     L = theCoordTransf->getInitialLength();
00134 
00135     if (L == 0.0)
00136  g3ErrorHandler->fatal("ElasticBeam2d::setDomain -- Element has zero length");
00137 }
00138 
00139 int
00140 ElasticBeam2d::commitState()
00141 {
00142     return theCoordTransf->commitState();
00143 }
00144 
00145 int
00146 ElasticBeam2d::revertToLastCommit()
00147 {
00148     return theCoordTransf->revertToLastCommit();
00149 }
00150 
00151 int
00152 ElasticBeam2d::revertToStart()
00153 {
00154     return theCoordTransf->revertToStart();
00155 }
00156 
00157 const Matrix &
00158 ElasticBeam2d::getTangentStiff(void)
00159 {
00160     theCoordTransf->update();
00161     
00162     const Vector &v = theCoordTransf->getBasicTrialDisp();
00163     
00164  double EoverL   = E/L;
00165  double EAoverL  = A*EoverL;   // EA/L
00166  double EIoverL2 = 2.0*I*EoverL;  // 2EI/L
00167  double EIoverL4 = 2.0*EIoverL2;  // 4EI/L
00168 
00169     q(0) = EAoverL*v(0);
00170     q(1) = EIoverL4*v(1) + EIoverL2*v(2);
00171     q(2) = EIoverL2*v(1) + EIoverL4*v(2);
00172 
00173     kb(0,0) = EAoverL;
00174     kb(1,1) = kb(2,2) = EIoverL4;
00175     kb(2,1) = kb(1,2) = EIoverL2;
00176 
00177     return theCoordTransf->getGlobalStiffMatrix(kb,q);
00178 }
00179 
00180 const Matrix &
00181 ElasticBeam2d::getSecantStiff(void)
00182 {
00183     return this->getTangentStiff();
00184 }
00185 
00186 const Matrix &
00187 ElasticBeam2d::getDamp(void)
00188 {
00189  K.Zero();
00190 
00191  return K;
00192 }
00193 
00194 const Matrix &
00195 ElasticBeam2d::getMass(void)
00196 { 
00197  K.Zero();
00198 
00199  if (rho > 0.0) {
00200   double m = 0.5*rho*L;
00201   
00202   K(0,0) = m;
00203   K(1,1) = m;
00204 
00205   K(3,3) = m;
00206   K(4,4) = m;
00207  }
00208 
00209     return K;
00210 }
00211 
00212 void 
00213 ElasticBeam2d::zeroLoad(void)
00214 {
00215  Q.Zero();
00216 
00217     return;
00218 }
00219 
00220 int
00221 ElasticBeam2d::addLoad(const Vector &moreLoad)
00222 {
00223     if (moreLoad.Size() != 6) {
00224  g3ErrorHandler->warning("ElasticBeam2d::addLoad: vector not of correct size");
00225  return -1;
00226     }
00227 
00228     //Q += moreLoad;
00229     Q.addVector(1.0, moreLoad, 1.0);
00230 
00231     return 0;
00232 }
00233 
00234 int
00235 ElasticBeam2d::addInertiaLoadToUnbalance(const Vector &accel)
00236 {
00237   if (rho == 0.0)
00238     return 0;
00239 
00240   // Get R * accel from the nodes
00241   const Vector &Raccel1 = node1Ptr->getRV(accel);
00242   const Vector &Raccel2 = node2Ptr->getRV(accel);
00243  
00244   if (3 != Raccel1.Size() || 3 != Raccel2.Size()) {
00245     g3ErrorHandler->warning("ElasticBeam2d::addInertiaLoadToUnbalance %s\n",
00246        "matrix and vector sizes are incompatable");
00247     return -1;
00248   }
00249     
00250   // Want to add ( - fact * M R * accel ) to unbalance
00251   // Take advantage of lumped mass matrix
00252   
00253   double m = 0.5*rho*L;
00254 
00255   Q(0) += -m * Raccel1(0);
00256   Q(1) += -m * Raccel1(1);
00257   
00258   Q(3) += -m * Raccel2(0);    
00259   Q(4) += -m * Raccel2(1);    
00260 
00261     return 0;
00262 }
00263 
00264 const Vector &
00265 ElasticBeam2d::getResistingForceIncInertia()
00266 { 
00267     P = this->getResistingForce();
00268     
00269     const Vector &accel1 = node1Ptr->getTrialAccel();
00270     const Vector &accel2 = node2Ptr->getTrialAccel();    
00271     
00272     double m = 0.5*rho*L;
00273 
00274     P(0) += m * accel1(0);
00275     P(1) += m * accel1(1);
00276     
00277     P(3) += m * accel2(0);    
00278     P(4) += m * accel2(1);
00279 
00280     return P;
00281 }
00282 
00283 const Vector &
00284 ElasticBeam2d::getResistingForce()
00285 {
00286     theCoordTransf->update();
00287 
00288     const Vector &v = theCoordTransf->getBasicTrialDisp();
00289     
00290  double EoverL   = E/L;
00291  double EAoverL  = A*EoverL;   // EA/L
00292  double EIoverL2 = 2.0*I*EoverL;  // 2EI/L
00293  double EIoverL4 = 2.0*EIoverL2;  // 4EI/L
00294 
00295     q(0) = EAoverL*v(0);
00296     q(1) = EIoverL4*v(1) + EIoverL2*v(2);
00297     q(2) = EIoverL2*v(1) + EIoverL4*v(2);
00298     
00299     static Vector dummy(2);
00300     
00301     P = theCoordTransf->getGlobalResistingForce(q, dummy);
00302 
00303     // P = P - Q;
00304     P.addVector(1.0, Q, -1.0);
00305 
00306     return P;
00307 }
00308 
00309 int
00310 ElasticBeam2d::sendSelf(int cTag, Channel &theChannel)
00311 {
00312  int res = 0;
00313 
00314     static Vector data(9);
00315     
00316  data(0) = A;
00317     data(1) = E; 
00318     data(2) = I; 
00319     data(3) = rho;
00320     data(4) = this->getTag();
00321     data(5) = connectedExternalNodes(0);
00322     data(6) = connectedExternalNodes(1);
00323  data(7) = theCoordTransf->getClassTag();
00324      
00325  int dbTag = theCoordTransf->getDbTag();
00326 
00327  if (dbTag == 0) {
00328   dbTag = theChannel.getDbTag();
00329   if (dbTag != 0)
00330    theCoordTransf->setDbTag(dbTag);
00331  }
00332 
00333  data(8) = dbTag;
00334 
00335  // Send the data vector
00336     res += theChannel.sendVector(this->getDbTag(), cTag, data);
00337     if (res < 0) {
00338   g3ErrorHandler->warning("%s -- could not send data Vector",
00339    "ElasticBeam2d::sendSelf");
00340   return res;
00341     }
00342 
00343     // Ask the CoordTransf to send itself
00344  res += theCoordTransf->sendSelf(cTag, theChannel);
00345  if (res < 0) {
00346   g3ErrorHandler->warning("%s -- could not send CoordTransf",
00347    "ElasticBeam2d::sendSelf");
00348   return res;
00349  }
00350 
00351     return res;
00352 }
00353 
00354 int
00355 ElasticBeam2d::recvSelf(int cTag, Channel &theChannel, FEM_ObjectBroker &theBroker)
00356 {
00357     int res = 0;
00358  
00359  static Vector data(9);
00360 
00361     res += theChannel.recvVector(this->getDbTag(), cTag, data);
00362     if (res < 0) {
00363   g3ErrorHandler->warning("%s -- could not receive data Vector",
00364    "ElasticBeam2d::recvSelf");
00365   return res;
00366     }
00367 
00368     A = data(0);
00369     E = data(1); 
00370     I = data(2); 
00371     rho = data(3);
00372     this->setTag((int)data(4));
00373     connectedExternalNodes(0) = (int)data(5);
00374     connectedExternalNodes(1) = (int)data(6);
00375 
00376  // Check if the CoordTransf is null; if so, get a new one
00377  int crdTag = (int)data(7);
00378  if (theCoordTransf == 0) {
00379   theCoordTransf = theBroker.getNewCrdTransf2d(crdTag);
00380   if (theCoordTransf == 0) {
00381    g3ErrorHandler->warning("%s -- could not get a CrdTransf2d",
00382     "ElasticBeam2d::recvSelf");
00383    return -1;
00384   }
00385  }
00386 
00387  // Check that the CoordTransf is of the right type; if not, delete
00388  // the current one and get a new one of the right type
00389  if (theCoordTransf->getClassTag() != crdTag) {
00390   delete theCoordTransf;
00391   theCoordTransf = theBroker.getNewCrdTransf2d(crdTag);
00392   if (theCoordTransf == 0) {
00393    g3ErrorHandler->warning("%s -- could not get a CrdTransf2d",
00394     "ElasticBeam2d::recvSelf");
00395    return -1;
00396   }
00397  }
00398 
00399  // Now, receive the CoordTransf
00400  theCoordTransf->setDbTag((int)data(8));
00401  res += theCoordTransf->recvSelf(cTag, theChannel, theBroker);
00402  if (res < 0) {
00403   g3ErrorHandler->warning("%s -- could not receive CoordTransf",
00404    "ElasticBeam2d::recvSelf");
00405   return res;
00406  }
00407 
00408  // Revert the crdtrasf to its last committed state
00409  theCoordTransf->revertToLastCommit();
00410 
00411     return res;
00412 }
00413 
00414 void
00415 ElasticBeam2d::Print(ostream &s, int flag)
00416 {
00417     s << "\nElasticBeam2d: " << this->getTag() << endl;
00418     s << "\tConnected Nodes: " << connectedExternalNodes ;
00419  s << "\tCoordTransf: " << theCoordTransf->getTag() << endl;
00420 }
00421 
00422 int
00423 ElasticBeam2d::displaySelf(Renderer &theViewer, int displayMode, float fact)
00424 {
00425     // first determine the end points of the beam based on
00426     // the display factor (a measure of the distorted image)
00427     const Vector &end1Crd = node1Ptr->getCrds();
00428     const Vector &end2Crd = node2Ptr->getCrds(); 
00429 
00430     const Vector &end1Disp = node1Ptr->getDisp();
00431     const Vector &end2Disp = node2Ptr->getDisp();
00432 
00433  static Vector v1(3);
00434  static Vector v2(3);
00435 
00436  for (int i = 0; i < 2; i++) {
00437   v1(i) = end1Crd(i) + end1Disp(i)*fact;
00438   v2(i) = end2Crd(i) + end2Disp(i)*fact;    
00439  }
00440  
00441  return theViewer.drawLine (v1, v2, 1.0, 1.0);
00442 }
00443 
00444 Response*
00445 ElasticBeam2d::setResponse(char **argv, int argc, Information &info)
00446 {
00447     // stiffness
00448     if (strcmp(argv[0],"stiffness") == 0)
00449   return new ElementResponse(this, 1, K);
00450 
00451     // global forces
00452     else if (strcmp(argv[0],"force") == 0 || strcmp(argv[0],"forces") == 0 ||
00453   strcmp(argv[0],"globalForce") == 0 || strcmp(argv[0],"globalForces") == 0)
00454   return new ElementResponse(this, 2, P);
00455 
00456  // local forces
00457     else if (strcmp(argv[0],"localForce") == 0 || strcmp(argv[0],"localForces") == 0)
00458   return new ElementResponse(this, 3, P);
00459 
00460     else
00461   return 0;
00462 }
00463 
00464 int
00465 ElasticBeam2d::getResponse (int responseID, Information &eleInfo)
00466 {
00467  double V;
00468 
00469     switch (responseID) {
00470   case 1: // stiffness
00471    return eleInfo.setMatrix(this->getTangentStiff());
00472 
00473   case 2: // global forces
00474    return eleInfo.setVector(this->getResistingForce());
00475 
00476   case 3: // local forces
00477    // Axial
00478    P(3) = q(0);
00479    P(0) = -q(0);
00480    // Moment
00481    P(2) = q(1);
00482    P(5) = q(2);
00483    // Shear
00484    V = (q(1)+q(2))/L;
00485    P(1) = V;
00486    P(4) = -V;
00487    return eleInfo.setVector(P);
00488 
00489   default:
00490    return -1;
00491     }
00492 }
00493 
00494 int
00495 ElasticBeam2d::setParameter (char **argv, int argc, Information &info)
00496 {
00497     // E of the beam interior
00498     if (strcmp(argv[0],"E") == 0) {
00499         info.theType = DoubleType;
00500         return 1;
00501     }
00502 
00503     // A of the beam interior
00504     else if (strcmp(argv[0],"A") == 0) {
00505         info.theType = DoubleType;
00506         return 2;
00507     }
00508 
00509     // I of the beam interior
00510     else if (strcmp(argv[0],"I") == 0) {
00511         info.theType = DoubleType;
00512         return 3;
00513     }
00514 
00515     else
00516         return -1;
00517 }
00518 
00519 int
00520 ElasticBeam2d::updateParameter (int parameterID, Information &info)
00521 {
00522  switch (parameterID) {
00523  case -1:
00524   return -1;
00525  case 1:
00526   this->E = info.theDouble;
00527   return 0;
00528  case 2:
00529   this->A = info.theDouble;
00530   return 0;
00531  case 3:
00532   this->I = info.theDouble;
00533   return 0;
00534  default:
00535   return -1;
00536  }
00537 }
Copyright Contact Us