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

DispBeamColumn3d.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.1 $
00022 // $Date: 2001/07/13 21:11:27 $
00023 // $Source: /usr/local/cvs/OpenSees/SRC/element/dispBeamColumn/DispBeamColumn3d.cpp,v $
00024 
00025 // Written: MHS
00026 // Created: Feb 2001
00027 //
00028 // Description: This file contains the class definition for DispBeamColumn3d.
00029 
00030 #include <DispBeamColumn3d.h>
00031 #include <Node.h>
00032 #include <SectionForceDeformation.h>
00033 #include <GaussQuadRule1d01.h>
00034 #include <CrdTransf3d.h>
00035 #include <Matrix.h>
00036 #include <Vector.h>
00037 #include <ID.h>
00038 #include <Renderer.h>
00039 #include <Domain.h>
00040 #include <string.h>
00041 #include <Information.h>
00042 #include <Channel.h>
00043 #include <FEM_ObjectBroker.h>
00044 #include <ElementResponse.h>
00045 
00046 #include <G3Globals.h>
00047 
00048 Matrix DispBeamColumn3d::K(12,12);
00049 Vector DispBeamColumn3d::P(12);
00050 double DispBeamColumn3d::workArea[200];
00051 
00052 DispBeamColumn3d::DispBeamColumn3d(int tag, int nd1, int nd2,
00053   int numSec, SectionForceDeformation &s,
00054   CrdTransf3d &coordTransf, double r)
00055 :Element (tag, ELE_TAG_DispBeamColumn3d), rho(r),
00056  Q(12), q(6), connectedExternalNodes(2), L(0.0),
00057  numSections(numSec), theSections(0), crdTransf(0)
00058 {
00059     // Allocate arrays of pointers to SectionForceDeformations
00060     theSections = new SectionForceDeformation *[numSections];
00061     
00062  if (theSections == 0)
00063      g3ErrorHandler->fatal("%s - failed to allocate section model pointer",
00064    "DispBeamColumn3d::DispBeamColumn3d");
00065 
00066     for (int i = 0; i < numSections; i++) {
00067 
00068   // Get copies of the material model for each integration point
00069   theSections[i] = s.getCopy();
00070    
00071   // Check allocation
00072   if (theSections[i] == 0)
00073    g3ErrorHandler->fatal("%s -- failed to get a copy of section model",
00074     "DispBeamColumn3d::DispBeamColumn3d");
00075  }
00076 
00077  crdTransf = coordTransf.getCopy();
00078 
00079  if (crdTransf == 0)
00080      g3ErrorHandler->fatal("%s - failed to copy coordinate transformation",
00081    "DispBeamColumn3d::DispBeamColumn3d");
00082 
00083  // Set connected external node IDs
00084     connectedExternalNodes(0) = nd1;
00085     connectedExternalNodes(1) = nd2;
00086 }
00087 
00088 DispBeamColumn3d::DispBeamColumn3d()
00089 :Element (0, ELE_TAG_DispBeamColumn3d), rho(0.0),
00090  Q(12), q(6), connectedExternalNodes(2), L(0.0),
00091  numSections(0), theSections(0), crdTransf(0)
00092 {
00093 
00094 }
00095 
00096 DispBeamColumn3d::~DispBeamColumn3d()
00097 {    
00098     for (int i = 0; i < numSections; i++) {
00099   if (theSections[i])
00100    delete theSections[i];
00101  }
00102 
00103     // Delete the array of pointers to SectionForceDeformation pointer arrays
00104     if (theSections)
00105   delete [] theSections;
00106 }
00107 
00108 int
00109 DispBeamColumn3d::getNumExternalNodes() const
00110 {
00111     return 2;
00112 }
00113 
00114 const ID&
00115 DispBeamColumn3d::getExternalNodes()
00116 {
00117     return connectedExternalNodes;
00118 }
00119 
00120 int
00121 DispBeamColumn3d::getNumDOF()
00122 {
00123     return 12;
00124 }
00125 
00126 void
00127 DispBeamColumn3d::setDomain(Domain *theDomain)
00128 {
00129  // Check Domain is not null - invoked when object removed from a domain
00130     if (theDomain == 0) {
00131  nd1Ptr = 0;
00132  nd2Ptr = 0;
00133  return;
00134     }
00135 
00136     int Nd1 = connectedExternalNodes(0);
00137     int Nd2 = connectedExternalNodes(1);
00138 
00139     nd1Ptr = theDomain->getNode(Nd1);
00140     nd2Ptr = theDomain->getNode(Nd2);
00141 
00142     if (nd1Ptr == 0 || nd2Ptr == 0) {
00143  //g3ErrorHandler->fatal("FATAL ERROR DispBeamColumn3d (tag: %d), node not found in domain",
00144  // this->getTag());
00145  
00146  return;
00147     }
00148 
00149     int dofNd1 = nd1Ptr->getNumberDOF();
00150     int dofNd2 = nd2Ptr->getNumberDOF();
00151     
00152     if (dofNd1 != 6 || dofNd2 != 6) {
00153  //g3ErrorHandler->fatal("FATAL ERROR DispBeamColumn3d (tag: %d), has differing number of DOFs at its nodes",
00154  // this->getTag());
00155  
00156  return;
00157     }
00158 
00159  if (crdTransf->initialize(nd1Ptr, nd2Ptr)) {
00160   // Add some error check
00161  }
00162 
00163  L = crdTransf->getInitialLength();
00164 
00165  if (L == 0.0) {
00166   // Add some error check
00167  }
00168 
00169     this->DomainComponent::setDomain(theDomain);
00170 
00171     this->update();
00172 }
00173 
00174 int
00175 DispBeamColumn3d::commitState()
00176 {
00177     int retVal = 0;
00178 
00179     // Loop over the integration points and commit the material states
00180     for (int i = 0; i < numSections; i++)
00181   retVal += theSections[i]->commitState();
00182 
00183     retVal += crdTransf->commitState();
00184 
00185     return retVal;
00186 }
00187 
00188 int
00189 DispBeamColumn3d::revertToLastCommit()
00190 {
00191     int retVal = 0;
00192 
00193     // Loop over the integration points and revert to last committed state
00194     for (int i = 0; i < numSections; i++)
00195   retVal += theSections[i]->revertToLastCommit();
00196 
00197     retVal += crdTransf->revertToLastCommit();
00198 
00199     return retVal;
00200 }
00201 
00202 int
00203 DispBeamColumn3d::revertToStart()
00204 {
00205     int retVal = 0;
00206 
00207     // Loop over the integration points and revert states to start
00208     for (int i = 0; i < numSections; i++)
00209   retVal += theSections[i]->revertToStart();
00210 
00211     retVal += crdTransf->revertToStart();
00212 
00213     return retVal;
00214 }
00215 
00216 int
00217 DispBeamColumn3d::update(void)
00218 {
00219  // Update the transformation
00220  crdTransf->update();
00221 
00222     // Get basic deformations
00223     static Vector v(6);
00224  v = crdTransf->getBasicTrialDisp();
00225 
00226  double oneOverL = 1.0/L;
00227  GaussQuadRule1d01 quadrat(numSections);
00228  const Matrix &pts = quadrat.getIntegrPointCoords();
00229  const Vector &wts = quadrat.getIntegrPointWeights();
00230 
00231  // Assuming member is prismatic ... have to move inside
00232  // the loop if it is not prismatic
00233  int order = theSections[0]->getOrder();
00234  const ID &code = theSections[0]->getType();
00235  Vector e(workArea, order);
00236 
00237  // Loop over the integration points
00238  for (int i = 0; i < numSections; i++) {
00239 
00240   double xi6 = 6.0*pts(i,0);
00241 
00242   int j;
00243   for (j = 0; j < order; j++) {
00244    switch(code(j)) {
00245    case SECTION_RESPONSE_P:
00246     e(j) = oneOverL*v(0); break;
00247    case SECTION_RESPONSE_MZ:
00248     e(j) = oneOverL*((xi6-4.0)*v(1) + (xi6-2.0)*v(2)); break;
00249    case SECTION_RESPONSE_MY:
00250     e(j) = oneOverL*((xi6-4.0)*v(3) + (xi6-2.0)*v(4)); break;
00251    case SECTION_RESPONSE_T:
00252     e(j) = oneOverL*v(5); break;
00253    default:
00254     e(j) = 0.0; break;
00255    }
00256   }
00257 
00258   // Set the section deformations
00259   theSections[i]->setTrialSectionDeformation(e);
00260  }
00261 
00262  return 0;
00263 }
00264 
00265 const Matrix&
00266 DispBeamColumn3d::getTangentStiff()
00267 {
00268  static Matrix kb(6,6);
00269 
00270  // Zero for integral
00271  kb.Zero();
00272  q.Zero();
00273 
00274  GaussQuadRule1d01 quadrat(numSections);
00275  const Matrix &pts = quadrat.getIntegrPointCoords();
00276  const Vector &wts = quadrat.getIntegrPointWeights();
00277 
00278  // Assuming member is prismatic ... have to move inside
00279  // the loop if it is not prismatic
00280  int order = theSections[0]->getOrder();
00281  const ID &code = theSections[0]->getType();
00282 
00283  double oneOverL = 1.0/L;
00284  Matrix ka(workArea, order, 6);
00285 
00286  // Loop over the integration points
00287  for (int i = 0; i < numSections; i++) {
00288 
00289   // Get the section tangent stiffness and stress resultant
00290   const Matrix &ks = theSections[i]->getSectionTangent();
00291   const Vector &s = theSections[i]->getStressResultant();
00292 
00293   double xi6 = 6.0*pts(i,0);
00294   ka.Zero();
00295 
00296   // Perform numerical integration
00297   //kb.addMatrixTripleProduct(1.0, *B, ks, wts(i)/L);
00298   double wti = wts(i)*oneOverL;
00299   double tmp;
00300   int j, k;
00301   for (j = 0; j < order; j++) {
00302    switch(code(j)) {
00303    case SECTION_RESPONSE_P:
00304     for (k = 0; k < order; k++)
00305      ka(k,0) += ks(k,j)*wti;
00306     break;
00307    case SECTION_RESPONSE_MZ:
00308     for (k = 0; k < order; k++) {
00309      tmp = ks(k,j)*wti;
00310      ka(k,1) += (xi6-4.0)*tmp;
00311      ka(k,2) += (xi6-2.0)*tmp;
00312     }
00313                 break;
00314    case SECTION_RESPONSE_MY:
00315     for (k = 0; k < order; k++) {
00316      tmp = ks(k,j)*wti;
00317      ka(k,3) += (xi6-4.0)*tmp;
00318      ka(k,4) += (xi6-2.0)*tmp;
00319     }
00320     break;
00321    case SECTION_RESPONSE_T:
00322     for (k = 0; k < order; k++)
00323      ka(k,5) += ks(k,j)*wti;
00324     break;
00325    default:
00326     break;
00327    }
00328   }
00329   for (j = 0; j < order; j++) {
00330    switch (code(j)) {
00331    case SECTION_RESPONSE_P:
00332     for (k = 0; k < 6; k++)
00333      kb(0,k) += ka(j,k);
00334     break;
00335    case SECTION_RESPONSE_MZ:
00336     for (k = 0; k < 6; k++) {
00337      tmp = ka(j,k);
00338      kb(1,k) += (xi6-4.0)*tmp;
00339      kb(2,k) += (xi6-2.0)*tmp;
00340     }
00341     break;
00342    case SECTION_RESPONSE_MY:
00343     for (k = 0; k < 6; k++) {
00344      tmp = ka(j,k);
00345      kb(3,k) += (xi6-4.0)*tmp;
00346      kb(4,k) += (xi6-2.0)*tmp;
00347     }
00348     break;
00349    case SECTION_RESPONSE_T:
00350     for (k = 0; k < 6; k++)
00351      kb(5,k) += ka(j,k);
00352     break;
00353    default:
00354     break;
00355    }
00356   }
00357 
00358   //q.addMatrixTransposeVector(1.0, *B, s, wts(i));
00359   double si;
00360   for (j = 0; j < order; j++) {
00361    si = s(j)*wts(i);
00362    switch(code(j)) {
00363    case SECTION_RESPONSE_P:
00364     q(0) += si; break;
00365    case SECTION_RESPONSE_MZ:
00366     q(1) += (xi6-4.0)*si; q(2) += (xi6-2.0)*si; break;
00367    case SECTION_RESPONSE_MY:
00368     q(3) += (xi6-4.0)*si; q(4) += (xi6-2.0)*si; break;
00369    case SECTION_RESPONSE_T:
00370     q(5) += si; break;
00371    default:
00372     break;
00373    }
00374   }
00375 
00376  }
00377 
00378  // Transform to global stiffness
00379  K = crdTransf->getGlobalStiffMatrix(kb, q);
00380 
00381  return K;
00382 }
00383 
00384 const Matrix&
00385 DispBeamColumn3d::getSecantStiff()
00386 {
00387  return this->getTangentStiff();
00388 }
00389 
00390 const Matrix&
00391 DispBeamColumn3d::getDamp()
00392 {
00393  K.Zero();
00394  
00395  return K;
00396 }
00397 
00398 const Matrix&
00399 DispBeamColumn3d::getMass()
00400 {
00401  K.Zero();
00402 
00403  if (rho == 0.0)
00404   return K;
00405 
00406  double m = 0.5*rho*L;
00407 
00408  K(0,0) = K(1,1) = K(2,2) = K(6,6) = K(7,7) = K(8,8) = m;
00409 
00410  return K;
00411 }
00412 
00413 void
00414 DispBeamColumn3d::zeroLoad(void)
00415 {
00416  Q.Zero();
00417 
00418  return;
00419 }
00420 
00421 int 
00422 DispBeamColumn3d::addLoad(const Vector &addLoad)
00423 {
00424  if (addLoad.Size() != 12) {
00425   g3ErrorHandler->warning("DispBeamColumn3d::addLoad %s\n",
00426     "Vector not of correct size");
00427   return -1;
00428  }
00429 
00430  // Add to the external nodal loads
00431  Q.addVector(1.0, addLoad, 1.0);
00432 
00433  return 0;
00434 }
00435 
00436 int 
00437 DispBeamColumn3d::addInertiaLoadToUnbalance(const Vector &accel)
00438 {
00439  // Check for a quick return
00440  if (rho == 0.0) 
00441   return 0;
00442 
00443  // Get R * accel from the nodes
00444  const Vector &Raccel1 = nd1Ptr->getRV(accel);
00445  const Vector &Raccel2 = nd2Ptr->getRV(accel);
00446 
00447     if (6 != Raccel1.Size() || 6 != Raccel2.Size()) {
00448   g3ErrorHandler->warning("DispBeamColumn3d::addInertiaLoadToUnbalance %s\n",
00449     "matrix and vector sizes are incompatable");
00450   return -1;
00451     }
00452 
00453  double m = 0.5*rho*L;
00454 
00455     // Want to add ( - fact * M R * accel ) to unbalance
00456  // Take advantage of lumped mass matrix
00457  Q(0) -= m*Raccel1(0);
00458  Q(1) -= m*Raccel1(1);
00459     Q(2) -= m*Raccel1(2);
00460  Q(6) -= m*Raccel2(0);
00461  Q(7) -= m*Raccel2(1);
00462     Q(8) -= m*Raccel2(2);
00463 
00464     return 0;
00465 }
00466 
00467 const Vector&
00468 DispBeamColumn3d::getResistingForce()
00469 {
00470  GaussQuadRule1d01 quadrat(numSections);
00471  const Matrix &pts = quadrat.getIntegrPointCoords();
00472  const Vector &wts = quadrat.getIntegrPointWeights();
00473 
00474  // Assuming member is prismatic ... have to move inside
00475  // the loop if it is not prismatic
00476  int order = theSections[0]->getOrder();
00477  const ID &code = theSections[0]->getType();
00478 
00479  // Zero for integration
00480  q.Zero();
00481 
00482  // Loop over the integration points
00483  for (int i = 0; i < numSections; i++) {
00484 
00485   double xi6 = 6.0*pts(i,0);
00486 
00487   // Get section stress resultant
00488   const Vector &s = theSections[i]->getStressResultant();
00489 
00490   // Perform numerical integration on internal force
00491   //q.addMatrixTransposeVector(1.0, *B, s, wts(i));
00492 
00493   double si;
00494   for (int j = 0; j < order; j++) {
00495    si = s(j)*wts(i);
00496    switch(code(j)) {
00497    case SECTION_RESPONSE_P:
00498     q(0) += si; break;
00499    case SECTION_RESPONSE_MZ:
00500     q(1) += (xi6-4.0)*si; q(2) += (xi6-2.0)*si; break;
00501    case SECTION_RESPONSE_MY:
00502     q(3) += (xi6-4.0)*si; q(4) += (xi6-2.0)*si; break;
00503    case SECTION_RESPONSE_T:
00504     q(5) += si; break;
00505    default:
00506     break;
00507    }
00508   }
00509 
00510  }
00511 
00512  // Transform forces
00513  static Vector dummy(3);  // No distributed loads
00514  P = crdTransf->getGlobalResistingForce(q,dummy);
00515 
00516  // Subtract other external nodal loads ... P_res = P_int - P_ext
00517  P.addVector(1.0, Q, -1.0);
00518 
00519  return P;
00520 }
00521 
00522 const Vector&
00523 DispBeamColumn3d::getResistingForceIncInertia()
00524 {
00525  // Check for a quick return
00526  if (rho == 0.0)
00527   return this->getResistingForce();
00528 
00529  const Vector &accel1 = nd1Ptr->getTrialAccel();
00530  const Vector &accel2 = nd2Ptr->getTrialAccel();
00531  
00532  // Compute the current resisting force
00533  this->getResistingForce();
00534 
00535  double m = 0.5*rho*L;
00536 
00537  P(0) += m*accel1(0);
00538  P(1) += m*accel1(1);
00539     P(2) += m*accel1(2);
00540  P(6) += m*accel2(0);
00541  P(7) += m*accel2(1);
00542     P(8) += m*accel2(2);
00543 
00544  return P;
00545 }
00546 
00547 int
00548 DispBeamColumn3d::sendSelf(int commitTag, Channel &theChannel)
00549 {
00550  return -1;
00551 }
00552 
00553 int
00554 DispBeamColumn3d::recvSelf(int commitTag, Channel &theChannel,
00555       FEM_ObjectBroker &theBroker)
00556 {
00557  return -1;
00558 }
00559 
00560 void
00561 DispBeamColumn3d::Print(ostream &s, int flag)
00562 {
00563  s << "\nDispBeamColumn3d, element id:  " << this->getTag() << endl;
00564  s << "\tConnected external nodes:  " << connectedExternalNodes;
00565  s << "\tmass density:  " << rho << endl;
00566  theSections[0]->Print(s,flag);
00567 }
00568 
00569 
00570 int
00571 DispBeamColumn3d::displaySelf(Renderer &theViewer, int displayMode, float fact)
00572 {
00573     // first determine the end points of the quad based on
00574     // the display factor (a measure of the distorted image)
00575     const Vector &end1Crd = nd1Ptr->getCrds();
00576     const Vector &end2Crd = nd2Ptr->getCrds(); 
00577 
00578     const Vector &end1Disp = nd1Ptr->getDisp();
00579     const Vector &end2Disp = nd2Ptr->getDisp();
00580 
00581  static Vector v1(3);
00582  static Vector v2(3);
00583 
00584  for (int i = 0; i < 3; i++) {
00585   v1(i) = end1Crd(i) + end1Disp(i)*fact;
00586   v2(i) = end2Crd(i) + end2Disp(i)*fact;    
00587  }
00588  
00589  return theViewer.drawLine (v1, v2, 1.0, 1.0);
00590 }
00591 
00592 Response*
00593 DispBeamColumn3d::setResponse(char **argv, int argc, Information &eleInfo)
00594 {
00595     // global force - 
00596     if (strcmp(argv[0],"forces") == 0 || strcmp(argv[0],"force") == 0
00597   || strcmp(argv[0],"globalForce") == 0 || strcmp(argv[0],"globalForces") == 0)
00598   return new ElementResponse(this, 1, P);
00599 
00600     // local force -
00601     else if (strcmp(argv[0],"localForce") == 0 || strcmp(argv[0],"localForces") == 0)
00602   return new ElementResponse(this, 2, P);
00603     
00604     // section response -
00605     else if (strcmp(argv[0],"section") ==0) {
00606   if (argc <= 2)
00607    return 0;
00608  
00609   int sectionNum = atoi(argv[1]);
00610   if (sectionNum > 0 && sectionNum <= numSections)
00611    return theSections[sectionNum-1]->setResponse(&argv[2], argc-2, eleInfo);
00612   else
00613    return 0;
00614  }
00615     
00616  else
00617   return 0;
00618 }
00619 
00620 int 
00621 DispBeamColumn3d::getResponse(int responseID, Information &eleInfo)
00622 {
00623   double V;
00624 
00625   switch (responseID) {
00626     case 1:  // global forces
00627       return eleInfo.setVector(P);
00628 
00629     case 2:
00630   // Axial
00631   P(6) = q(0);
00632   P(0) = -q(0);
00633 
00634   // Torsion
00635   P(11) = q(5);
00636   P(5)  = -q(5);
00637 
00638   // Moments about z and shears along y
00639   P(2) = q(1);
00640   P(8) = q(2);
00641   V = (q(1)+q(2))/L;
00642   P(1) = V;
00643   P(7) = -V;
00644 
00645   // Moments about y and shears along z
00646   P(4)  = q(3);
00647   P(10) = q(4);
00648   V = (q(3)+q(4))/L;
00649   P(3) = -V;
00650   P(9) = V;
00651       return eleInfo.setVector(P);
00652       
00653     default: 
00654    return -1;
00655   }
00656 }
Copyright Contact Us