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.21 $
00022 // $Date: 2006/08/04 18:44:02 $
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 <CrdTransf3d.h>
00034 #include <Matrix.h>
00035 #include <Vector.h>
00036 #include <ID.h>
00037 #include <Renderer.h>
00038 #include <Domain.h>
00039 #include <string.h>
00040 #include <Information.h>
00041 #include <Channel.h>
00042 #include <FEM_ObjectBroker.h>
00043 #include <ElementResponse.h>
00044 #include <ElementalLoad.h>
00045 
00046 Matrix DispBeamColumn3d::K(12,12);
00047 Vector DispBeamColumn3d::P(12);
00048 double DispBeamColumn3d::workArea[200];
00049 GaussQuadRule1d01 DispBeamColumn3d::quadRule;
00050 
00051 DispBeamColumn3d::DispBeamColumn3d(int tag, int nd1, int nd2,
00052                                    int numSec, SectionForceDeformation **s,
00053                                    CrdTransf3d &coordTransf, double r)
00054 :Element (tag, ELE_TAG_DispBeamColumn3d),
00055 numSections(numSec), theSections(0), crdTransf(0),
00056 connectedExternalNodes(2), 
00057 Q(12), q(6), rho(r)
00058 {
00059   // Allocate arrays of pointers to SectionForceDeformations
00060   theSections = new SectionForceDeformation *[numSections];
00061   
00062   if (theSections == 0) {
00063     opserr << "DispBeamColumn3d::DispBeamColumn3d - failed to allocate section model pointer\n";
00064     exit(-1);
00065   }
00066   
00067   for (int i = 0; i < numSections; i++) {
00068     
00069     // Get copies of the material model for each integration point
00070     theSections[i] = s[i]->getCopy();
00071     
00072     // Check allocation
00073     if (theSections[i] == 0) {
00074       opserr << "DispBeamColumn3d::DispBeamColumn3d -- failed to get a copy of section model\n";
00075       exit(-1);
00076     }
00077   }
00078   
00079   crdTransf = coordTransf.getCopy();
00080   
00081   if (crdTransf == 0) {
00082     opserr << "DispBeamColumn3d::DispBeamColumn3d - failed to copy coordinate transformation\n";
00083     exit(-1);
00084   }
00085   
00086   // Set connected external node IDs
00087   connectedExternalNodes(0) = nd1;
00088   connectedExternalNodes(1) = nd2;
00089 
00090 
00091   theNodes[0] = 0;
00092   theNodes[1] = 0;
00093 
00094   q0[0] = 0.0;
00095   q0[1] = 0.0;
00096   q0[2] = 0.0;
00097   q0[3] = 0.0;
00098   q0[4] = 0.0;
00099 
00100   p0[0] = 0.0;
00101   p0[1] = 0.0;
00102   p0[2] = 0.0;
00103   p0[3] = 0.0;
00104   p0[4] = 0.0;
00105 }
00106 
00107 DispBeamColumn3d::DispBeamColumn3d()
00108 :Element (0, ELE_TAG_DispBeamColumn3d),
00109 numSections(0), theSections(0), crdTransf(0),
00110 connectedExternalNodes(2), 
00111 Q(12), q(6), rho(0.0)
00112 {
00113   q0[0] = 0.0;
00114   q0[1] = 0.0;
00115   q0[2] = 0.0;
00116   q0[3] = 0.0;
00117   q0[4] = 0.0;
00118 
00119   p0[0] = 0.0;
00120   p0[1] = 0.0;
00121   p0[2] = 0.0;
00122   p0[3] = 0.0;
00123   p0[4] = 0.0;
00124 
00125   theNodes[0] = 0;
00126   theNodes[1] = 0;
00127 }
00128 
00129 DispBeamColumn3d::~DispBeamColumn3d()
00130 {    
00131   for (int i = 0; i < numSections; i++) {
00132     if (theSections[i])
00133       delete theSections[i];
00134   }
00135   
00136   // Delete the array of pointers to SectionForceDeformation pointer arrays
00137   if (theSections)
00138     delete [] theSections;
00139   
00140   if (crdTransf)
00141     delete crdTransf;
00142 }
00143 
00144 int
00145 DispBeamColumn3d::getNumExternalNodes() const
00146 {
00147     return 2;
00148 }
00149 
00150 const ID&
00151 DispBeamColumn3d::getExternalNodes()
00152 {
00153     return connectedExternalNodes;
00154 }
00155 
00156 Node **
00157 DispBeamColumn3d::getNodePtrs()
00158 {
00159 
00160     return theNodes;
00161 }
00162 
00163 int
00164 DispBeamColumn3d::getNumDOF()
00165 {
00166     return 12;
00167 }
00168 
00169 void
00170 DispBeamColumn3d::setDomain(Domain *theDomain)
00171 {
00172         // Check Domain is not null - invoked when object removed from a domain
00173     if (theDomain == 0) {
00174         theNodes[0] = 0;
00175         theNodes[1] = 0;
00176         return;
00177     }
00178 
00179     int Nd1 = connectedExternalNodes(0);
00180     int Nd2 = connectedExternalNodes(1);
00181 
00182     theNodes[0] = theDomain->getNode(Nd1);
00183     theNodes[1] = theDomain->getNode(Nd2);
00184 
00185     if (theNodes[0] == 0 || theNodes[1] == 0) {
00186         //opserr << "FATAL ERROR DispBeamColumn3d (tag: %d), node not found in domain",
00187         //      this->getTag());
00188         
00189         return;
00190     }
00191 
00192     int dofNd1 = theNodes[0]->getNumberDOF();
00193     int dofNd2 = theNodes[1]->getNumberDOF();
00194     
00195     if (dofNd1 != 6 || dofNd2 != 6) {
00196         //opserr << "FATAL ERROR DispBeamColumn3d (tag: %d), has differing number of DOFs at its nodes",
00197         //      this->getTag());
00198         
00199         return;
00200     }
00201 
00202         if (crdTransf->initialize(theNodes[0], theNodes[1])) {
00203                 // Add some error check
00204         }
00205 
00206         double L = crdTransf->getInitialLength();
00207 
00208         if (L == 0.0) {
00209                 // Add some error check
00210         }
00211 
00212     this->DomainComponent::setDomain(theDomain);
00213 
00214         this->update();
00215 }
00216 
00217 int
00218 DispBeamColumn3d::commitState()
00219 {
00220     int retVal = 0;
00221 
00222     // call element commitState to do any base class stuff
00223     if ((retVal = this->Element::commitState()) != 0) {
00224       opserr << "DispBeamColumn3d::commitState () - failed in base class";
00225     }    
00226 
00227     // Loop over the integration points and commit the material states
00228     for (int i = 0; i < numSections; i++)
00229                 retVal += theSections[i]->commitState();
00230 
00231     retVal += crdTransf->commitState();
00232 
00233     return retVal;
00234 }
00235 
00236 int
00237 DispBeamColumn3d::revertToLastCommit()
00238 {
00239     int retVal = 0;
00240 
00241     // Loop over the integration points and revert to last committed state
00242     for (int i = 0; i < numSections; i++)
00243                 retVal += theSections[i]->revertToLastCommit();
00244 
00245     retVal += crdTransf->revertToLastCommit();
00246 
00247     return retVal;
00248 }
00249 
00250 int
00251 DispBeamColumn3d::revertToStart()
00252 {
00253     int retVal = 0;
00254 
00255     // Loop over the integration points and revert states to start
00256     for (int i = 0; i < numSections; i++)
00257                 retVal += theSections[i]->revertToStart();
00258 
00259     retVal += crdTransf->revertToStart();
00260 
00261     return retVal;
00262 }
00263 
00264 int
00265 DispBeamColumn3d::update(void)
00266 {
00267   // Update the transformation
00268   crdTransf->update();
00269   
00270   // Get basic deformations
00271   const Vector &v = crdTransf->getBasicTrialDisp();
00272   
00273   double L = crdTransf->getInitialLength();
00274   double oneOverL = 1.0/L;
00275   const Matrix &pts = quadRule.getIntegrPointCoords(numSections);
00276   
00277   // Loop over the integration points
00278   for (int i = 0; i < numSections; i++) {
00279 
00280     int order = theSections[i]->getOrder();
00281     const ID &code = theSections[i]->getType();
00282 
00283     Vector e(workArea, order);
00284       
00285     double xi6 = 6.0*pts(i,0);
00286     
00287     int j;
00288     for (j = 0; j < order; j++) {
00289       switch(code(j)) {
00290       case SECTION_RESPONSE_P:
00291         e(j) = oneOverL*v(0);
00292         break;
00293       case SECTION_RESPONSE_MZ:
00294         e(j) = oneOverL*((xi6-4.0)*v(1) + (xi6-2.0)*v(2));
00295         break;
00296       case SECTION_RESPONSE_MY:
00297         e(j) = oneOverL*((xi6-4.0)*v(3) + (xi6-2.0)*v(4));
00298         break;
00299       case SECTION_RESPONSE_T:
00300         e(j) = oneOverL*v(5);
00301         break;
00302       default:
00303         e(j) = 0.0;
00304         break;
00305       }
00306     }
00307     
00308     // Set the section deformations
00309     theSections[i]->setTrialSectionDeformation(e);
00310   }
00311   
00312   return 0;
00313 }
00314 
00315 const Matrix&
00316 DispBeamColumn3d::getTangentStiff()
00317 {
00318   static Matrix kb(6,6);
00319   
00320   // Zero for integral
00321   kb.Zero();
00322   q.Zero();
00323   
00324   const Matrix &pts = quadRule.getIntegrPointCoords(numSections);
00325   const Vector &wts = quadRule.getIntegrPointWeights(numSections);
00326   
00327   double L = crdTransf->getInitialLength();
00328   double oneOverL = 1.0/L;
00329   
00330   // Loop over the integration points
00331   for (int i = 0; i < numSections; i++) {
00332     
00333     int order = theSections[i]->getOrder();
00334     const ID &code = theSections[i]->getType();
00335 
00336     Matrix ka(workArea, order, 6);
00337     ka.Zero();
00338 
00339     double xi6 = 6.0*pts(i,0);
00340 
00341     // Get the section tangent stiffness and stress resultant
00342     const Matrix &ks = theSections[i]->getSectionTangent();
00343     const Vector &s = theSections[i]->getStressResultant();
00344         
00345     // Perform numerical integration
00346     //kb.addMatrixTripleProduct(1.0, *B, ks, wts(i)/L);
00347     double wti = wts(i)*oneOverL;
00348     double tmp;
00349     int j, k;
00350     for (j = 0; j < order; j++) {
00351       switch(code(j)) {
00352       case SECTION_RESPONSE_P:
00353         for (k = 0; k < order; k++)
00354           ka(k,0) += ks(k,j)*wti;
00355         break;
00356       case SECTION_RESPONSE_MZ:
00357         for (k = 0; k < order; k++) {
00358           tmp = ks(k,j)*wti;
00359           ka(k,1) += (xi6-4.0)*tmp;
00360           ka(k,2) += (xi6-2.0)*tmp;
00361         }
00362         break;
00363       case SECTION_RESPONSE_MY:
00364         for (k = 0; k < order; k++) {
00365           tmp = ks(k,j)*wti;
00366           ka(k,3) += (xi6-4.0)*tmp;
00367           ka(k,4) += (xi6-2.0)*tmp;
00368         }
00369         break;
00370       case SECTION_RESPONSE_T:
00371         for (k = 0; k < order; k++)
00372           ka(k,5) += ks(k,j)*wti;
00373         break;
00374       default:
00375         break;
00376       }
00377     }
00378     for (j = 0; j < order; j++) {
00379       switch (code(j)) {
00380       case SECTION_RESPONSE_P:
00381         for (k = 0; k < 6; k++)
00382           kb(0,k) += ka(j,k);
00383         break;
00384       case SECTION_RESPONSE_MZ:
00385         for (k = 0; k < 6; k++) {
00386           tmp = ka(j,k);
00387           kb(1,k) += (xi6-4.0)*tmp;
00388           kb(2,k) += (xi6-2.0)*tmp;
00389         }
00390         break;
00391       case SECTION_RESPONSE_MY:
00392         for (k = 0; k < 6; k++) {
00393           tmp = ka(j,k);
00394           kb(3,k) += (xi6-4.0)*tmp;
00395           kb(4,k) += (xi6-2.0)*tmp;
00396         }
00397         break;
00398       case SECTION_RESPONSE_T:
00399         for (k = 0; k < 6; k++)
00400           kb(5,k) += ka(j,k);
00401         break;
00402       default:
00403         break;
00404       }
00405     }
00406     
00407     //q.addMatrixTransposeVector(1.0, *B, s, wts(i));
00408     double si;
00409     for (j = 0; j < order; j++) {
00410       si = s(j)*wts(i);
00411       switch(code(j)) {
00412       case SECTION_RESPONSE_P:
00413         q(0) += si;
00414         break;
00415       case SECTION_RESPONSE_MZ:
00416         q(1) += (xi6-4.0)*si; q(2) += (xi6-2.0)*si;
00417         break;
00418       case SECTION_RESPONSE_MY:
00419         q(3) += (xi6-4.0)*si; q(4) += (xi6-2.0)*si;
00420         break;
00421       case SECTION_RESPONSE_T:
00422         q(5) += si;
00423         break;
00424       default:
00425         break;
00426       }
00427     }
00428     
00429   }
00430   
00431   q(0) += q0[0];
00432   q(1) += q0[1];
00433   q(2) += q0[2];
00434   q(3) += q0[3];
00435   q(4) += q0[4];
00436 
00437   // Transform to global stiffness
00438   K = crdTransf->getGlobalStiffMatrix(kb, q);
00439   
00440   return K;
00441 }
00442 
00443 const Matrix&
00444 DispBeamColumn3d::getInitialBasicStiff()
00445 {
00446   static Matrix kb(6,6);
00447   
00448   // Zero for integral
00449   kb.Zero();
00450   
00451   const Matrix &pts = quadRule.getIntegrPointCoords(numSections);
00452   const Vector &wts = quadRule.getIntegrPointWeights(numSections);
00453   
00454   double L = crdTransf->getInitialLength();
00455   double oneOverL = 1.0/L;
00456   
00457   // Loop over the integration points
00458   for (int i = 0; i < numSections; i++) {
00459 
00460     int order = theSections[i]->getOrder();
00461     const ID &code = theSections[i]->getType();
00462     
00463     Matrix ka(workArea, order, 6);
00464     ka.Zero();
00465     
00466     double xi6 = 6.0*pts(i,0);
00467     
00468     // Get the section tangent stiffness and stress resultant
00469     const Matrix &ks = theSections[i]->getInitialTangent();
00470     
00471     // Perform numerical integration
00472     //kb.addMatrixTripleProduct(1.0, *B, ks, wts(i)/L);
00473     double wti = wts(i)*oneOverL;
00474     double tmp;
00475     int j, k;
00476     for (j = 0; j < order; j++) {
00477       switch(code(j)) {
00478       case SECTION_RESPONSE_P:
00479         for (k = 0; k < order; k++)
00480           ka(k,0) += ks(k,j)*wti;
00481         break;
00482       case SECTION_RESPONSE_MZ:
00483         for (k = 0; k < order; k++) {
00484           tmp = ks(k,j)*wti;
00485           ka(k,1) += (xi6-4.0)*tmp;
00486           ka(k,2) += (xi6-2.0)*tmp;
00487         }
00488         break;
00489       case SECTION_RESPONSE_MY:
00490         for (k = 0; k < order; k++) {
00491           tmp = ks(k,j)*wti;
00492           ka(k,3) += (xi6-4.0)*tmp;
00493           ka(k,4) += (xi6-2.0)*tmp;
00494         }
00495         break;
00496       case SECTION_RESPONSE_T:
00497         for (k = 0; k < order; k++)
00498           ka(k,5) += ks(k,j)*wti;
00499         break;
00500       default:
00501         break;
00502       }
00503     }
00504     for (j = 0; j < order; j++) {
00505       switch (code(j)) {
00506       case SECTION_RESPONSE_P:
00507         for (k = 0; k < 6; k++)
00508           kb(0,k) += ka(j,k);
00509         break;
00510       case SECTION_RESPONSE_MZ:
00511         for (k = 0; k < 6; k++) {
00512           tmp = ka(j,k);
00513           kb(1,k) += (xi6-4.0)*tmp;
00514           kb(2,k) += (xi6-2.0)*tmp;
00515         }
00516         break;
00517       case SECTION_RESPONSE_MY:
00518         for (k = 0; k < 6; k++) {
00519           tmp = ka(j,k);
00520           kb(3,k) += (xi6-4.0)*tmp;
00521           kb(4,k) += (xi6-2.0)*tmp;
00522         }
00523         break;
00524       case SECTION_RESPONSE_T:
00525         for (k = 0; k < 6; k++)
00526           kb(5,k) += ka(j,k);
00527         break;
00528       default:
00529         break;
00530       }
00531     }
00532     
00533   }
00534   
00535   return kb;
00536 }
00537 
00538 const Matrix&
00539 DispBeamColumn3d::getInitialStiff()
00540 {
00541   const Matrix &kb = this->getInitialBasicStiff();
00542 
00543   // Transform to global stiffness
00544   K = crdTransf->getInitialGlobalStiffMatrix(kb);
00545   
00546   return K;
00547 }
00548 
00549 const Matrix&
00550 DispBeamColumn3d::getMass()
00551 {
00552   K.Zero();
00553   
00554   if (rho == 0.0)
00555     return K;
00556   
00557   double L = crdTransf->getInitialLength();
00558   double m = 0.5*rho*L;
00559   
00560   K(0,0) = K(1,1) = K(2,2) = K(6,6) = K(7,7) = K(8,8) = m;
00561   
00562   return K;
00563 }
00564 
00565 void
00566 DispBeamColumn3d::zeroLoad(void)
00567 {
00568   Q.Zero();
00569 
00570   q0[0] = 0.0;
00571   q0[1] = 0.0;
00572   q0[2] = 0.0;
00573   q0[3] = 0.0;
00574   q0[4] = 0.0;
00575 
00576   p0[0] = 0.0;
00577   p0[1] = 0.0;
00578   p0[2] = 0.0;
00579   p0[3] = 0.0;
00580   p0[4] = 0.0;
00581 
00582   return;
00583 }
00584 
00585 int 
00586 DispBeamColumn3d::addLoad(ElementalLoad *theLoad, double loadFactor)
00587 {
00588   int type;
00589   const Vector &data = theLoad->getData(type, loadFactor);
00590   double L = crdTransf->getInitialLength();
00591 
00592   if (type == LOAD_TAG_Beam3dUniformLoad) {
00593     double wy = data(0)*loadFactor;  // Transverse
00594     double wz = data(1)*loadFactor;  // Transverse
00595     double wx = data(2)*loadFactor;  // Axial (+ve from node I to J)
00596 
00597     double Vy = 0.5*wy*L;
00598     double Mz = Vy*L/6.0; // wy*L*L/12
00599     double Vz = 0.5*wz*L;
00600     double My = Vz*L/6.0; // wz*L*L/12
00601     double P = wx*L;
00602 
00603     // Reactions in basic system
00604     p0[0] -= P;
00605     p0[1] -= Vy;
00606     p0[2] -= Vy;
00607     p0[3] -= Vz;
00608     p0[4] -= Vz;
00609 
00610     // Fixed end forces in basic system
00611     q0[0] -= 0.5*P;
00612     q0[1] -= Mz;
00613     q0[2] += Mz;
00614     q0[3] += My;
00615     q0[4] -= My;
00616   }
00617   else if (type == LOAD_TAG_Beam3dPointLoad) {
00618     double Py = data(0)*loadFactor;
00619     double Pz = data(1)*loadFactor;
00620     double N  = data(2)*loadFactor;
00621     double aOverL = data(3);
00622 
00623     if (aOverL < 0.0 || aOverL > 1.0)
00624       return 0;
00625 
00626     double a = aOverL*L;
00627     double b = L-a;
00628 
00629     // Reactions in basic system
00630     p0[0] -= N;
00631     double V1, V2;
00632     V1 = Py*(1.0-aOverL);
00633     V2 = Py*aOverL;
00634     p0[1] -= V1;
00635     p0[2] -= V2;
00636     V1 = Pz*(1.0-aOverL);
00637     V2 = Pz*aOverL;
00638     p0[3] -= V1;
00639     p0[4] -= V2;
00640 
00641     double L2 = 1.0/(L*L);
00642     double a2 = a*a;
00643     double b2 = b*b;
00644 
00645     // Fixed end forces in basic system
00646     q0[0] -= N*aOverL;
00647     double M1, M2;
00648     M1 = -a * b2 * Py * L2;
00649     M2 = a2 * b * Py * L2;
00650     q0[1] += M1;
00651     q0[2] += M2;
00652     M1 = -a * b2 * Pz * L2;
00653     M2 = a2 * b * Pz * L2;
00654     q0[3] -= M1;
00655     q0[4] -= M2;
00656   }
00657   else {
00658     opserr << "DispBeamColumn2d::addLoad() -- load type unknown for element with tag: " << 
00659       this->getTag() << endln;
00660     return -1;
00661   }
00662 
00663   return 0;
00664 }
00665 
00666 int 
00667 DispBeamColumn3d::addInertiaLoadToUnbalance(const Vector &accel)
00668 {
00669   // Check for a quick return
00670   if (rho == 0.0) 
00671     return 0;
00672   
00673   // Get R * accel from the nodes
00674   const Vector &Raccel1 = theNodes[0]->getRV(accel);
00675   const Vector &Raccel2 = theNodes[1]->getRV(accel);
00676   
00677   if (6 != Raccel1.Size() || 6 != Raccel2.Size()) {
00678     opserr << "DispBeamColumn3d::addInertiaLoadToUnbalance matrix and vector sizes are incompatable\n";
00679     return -1;
00680   }
00681   
00682   double L = crdTransf->getInitialLength();
00683   double m = 0.5*rho*L;
00684   
00685   // Want to add ( - fact * M R * accel ) to unbalance
00686   // Take advantage of lumped mass matrix
00687   Q(0) -= m*Raccel1(0);
00688   Q(1) -= m*Raccel1(1);
00689   Q(2) -= m*Raccel1(2);
00690   Q(6) -= m*Raccel2(0);
00691   Q(7) -= m*Raccel2(1);
00692   Q(8) -= m*Raccel2(2);
00693   
00694   return 0;
00695 }
00696 
00697 const Vector&
00698 DispBeamColumn3d::getResistingForce()
00699 {
00700   const Matrix &pts = quadRule.getIntegrPointCoords(numSections);
00701   const Vector &wts = quadRule.getIntegrPointWeights(numSections);
00702   
00703   // Zero for integration
00704   q.Zero();
00705   
00706   // Loop over the integration points
00707   for (int i = 0; i < numSections; i++) {
00708     
00709     int order = theSections[i]->getOrder();
00710     const ID &code = theSections[i]->getType();
00711 
00712     double xi6 = 6.0*pts(i,0);
00713     
00714     // Get section stress resultant
00715     const Vector &s = theSections[i]->getStressResultant();
00716     
00717     // Perform numerical integration on internal force
00718     //q.addMatrixTransposeVector(1.0, *B, s, wts(i));
00719     
00720     double si;
00721     for (int j = 0; j < order; j++) {
00722       si = s(j)*wts(i);
00723       switch(code(j)) {
00724       case SECTION_RESPONSE_P:
00725         q(0) += si;
00726         break;
00727       case SECTION_RESPONSE_MZ:
00728         q(1) += (xi6-4.0)*si; q(2) += (xi6-2.0)*si;
00729         break;
00730       case SECTION_RESPONSE_MY:
00731         q(3) += (xi6-4.0)*si; q(4) += (xi6-2.0)*si;
00732         break;
00733       case SECTION_RESPONSE_T:
00734         q(5) += si;
00735         break;
00736       default:
00737         break;
00738       }
00739     }
00740     
00741   }
00742   
00743   q(0) += q0[0];
00744   q(1) += q0[1];
00745   q(2) += q0[2];
00746   q(3) += q0[3];
00747   q(4) += q0[4];
00748 
00749   // Transform forces
00750   Vector p0Vec(p0, 5);
00751   P = crdTransf->getGlobalResistingForce(q, p0Vec);
00752   
00753   // Subtract other external nodal loads ... P_res = P_int - P_ext
00754   P.addVector(1.0, Q, -1.0);
00755   
00756   return P;
00757 }
00758 
00759 const Vector&
00760 DispBeamColumn3d::getResistingForceIncInertia()
00761 {
00762   this->getResistingForce();
00763   
00764   if (rho != 0.0) {
00765     const Vector &accel1 = theNodes[0]->getTrialAccel();
00766     const Vector &accel2 = theNodes[1]->getTrialAccel();
00767     
00768     // Compute the current resisting force
00769     this->getResistingForce();
00770     
00771     double L = crdTransf->getInitialLength();
00772     double m = 0.5*rho*L;
00773   
00774     P(0) += m*accel1(0);
00775     P(1) += m*accel1(1);
00776     P(2) += m*accel1(2);
00777     P(6) += m*accel2(0);
00778     P(7) += m*accel2(1);
00779     P(8) += m*accel2(2);
00780 
00781     // add the damping forces if rayleigh damping
00782     if (alphaM != 0.0 || betaK != 0.0 || betaK0 != 0.0 || betaKc != 0.0)
00783       P += this->getRayleighDampingForces();
00784 
00785   } else {
00786 
00787     // add the damping forces if rayleigh damping
00788     if (betaK != 0.0 || betaK0 != 0.0 || betaKc != 0.0)
00789       P += this->getRayleighDampingForces();
00790   }
00791   
00792   return P;
00793 }
00794 
00795 int
00796 DispBeamColumn3d::sendSelf(int commitTag, Channel &theChannel)
00797 {
00798   // place the integer data into an ID
00799 
00800   int dbTag = this->getDbTag();
00801   int i, j;
00802   int loc = 0;
00803   
00804   static ID idData(7);  // one bigger than needed so no clash later
00805   idData(0) = this->getTag();
00806   idData(1) = connectedExternalNodes(0);
00807   idData(2) = connectedExternalNodes(1);
00808   idData(3) = numSections;
00809   idData(4) = crdTransf->getClassTag();
00810   int crdTransfDbTag  = crdTransf->getDbTag();
00811   if (crdTransfDbTag  == 0) {
00812     crdTransfDbTag = theChannel.getDbTag();
00813     if (crdTransfDbTag  != 0) 
00814       crdTransf->setDbTag(crdTransfDbTag);
00815   }
00816   idData(5) = crdTransfDbTag;
00817   
00818   if (theChannel.sendID(dbTag, commitTag, idData) < 0) {
00819     opserr << "DispBeamColumn3d::sendSelf() - failed to send ID data\n";
00820      return -1;
00821   }    
00822 
00823   // send the coordinate transformation
00824   
00825   if (crdTransf->sendSelf(commitTag, theChannel) < 0) {
00826      opserr << "DispBeamColumn3d::sendSelf() - failed to send crdTranf\n";
00827      return -1;
00828   }      
00829 
00830   
00831   //
00832   // send an ID for the sections containing each sections dbTag and classTag
00833   // if section ha no dbTag get one and assign it
00834   //
00835 
00836   ID idSections(2*numSections);
00837   loc = 0;
00838   for (i = 0; i<numSections; i++) {
00839     int sectClassTag = theSections[i]->getClassTag();
00840     int sectDbTag = theSections[i]->getDbTag();
00841     if (sectDbTag == 0) {
00842       sectDbTag = theChannel.getDbTag();
00843       theSections[i]->setDbTag(sectDbTag);
00844     }
00845 
00846     idSections(loc) = sectClassTag;
00847     idSections(loc+1) = sectDbTag;
00848     loc += 2;
00849   }
00850 
00851   if (theChannel.sendID(dbTag, commitTag, idSections) < 0)  {
00852     opserr << "DispBeamColumn3d::sendSelf() - failed to send ID data\n";
00853     return -1;
00854   }    
00855 
00856   //
00857   // send the sections
00858   //
00859   
00860   for (j = 0; j<numSections; j++) {
00861     if (theSections[j]->sendSelf(commitTag, theChannel) < 0) {
00862       opserr << "DispBeamColumn3d::sendSelf() - section " << j << "failed to send itself\n";
00863       return -1;
00864     }
00865   }
00866 
00867   return 0;
00868 }
00869 
00870 int
00871 DispBeamColumn3d::recvSelf(int commitTag, Channel &theChannel,
00872                                                 FEM_ObjectBroker &theBroker)
00873 {
00874   //
00875   // receive the integer data containing tag, numSections and coord transformation info
00876   //
00877   int dbTag = this->getDbTag();
00878   int i;
00879   
00880   static ID idData(7); // one bigger than needed so no clash with section ID
00881 
00882   if (theChannel.recvID(dbTag, commitTag, idData) < 0)  {
00883     opserr << "DispBeamColumn3d::recvSelf() - failed to recv ID data\n";
00884     return -1;
00885   }    
00886 
00887   this->setTag(idData(0));
00888   connectedExternalNodes(0) = idData(1);
00889   connectedExternalNodes(1) = idData(2);
00890   
00891   int crdTransfClassTag = idData(4);
00892   int crdTransfDbTag = idData(5);
00893 
00894   // create a new crdTransf object if one needed
00895   if (crdTransf == 0 || crdTransf->getClassTag() != crdTransfClassTag) {
00896       if (crdTransf != 0)
00897           delete crdTransf;
00898 
00899       crdTransf = theBroker.getNewCrdTransf3d(crdTransfClassTag);
00900 
00901       if (crdTransf == 0) {
00902         opserr << "DispBeamColumn3d::recvSelf() - " <<
00903           "failed to obtain a CrdTrans object with classTag" <<
00904           crdTransfClassTag << endln;
00905         return -2;        
00906       }
00907   }
00908 
00909   crdTransf->setDbTag(crdTransfDbTag);
00910 
00911   // invoke recvSelf on the crdTransf object
00912   if (crdTransf->recvSelf(commitTag, theChannel, theBroker) < 0) {
00913     opserr << "DispBeamColumn3d::sendSelf() - failed to recv crdTranf\n";
00914     return -3;
00915   }      
00916   
00917   //
00918   // recv an ID for the sections containing each sections dbTag and classTag
00919   //
00920 
00921   ID idSections(2*idData(3));
00922   int loc = 0;
00923 
00924   if (theChannel.recvID(dbTag, commitTag, idSections) < 0)  {
00925     opserr << "DispBeamColumn3d::recvSelf() - failed to recv ID data\n";
00926     return -1;
00927   }    
00928 
00929   //
00930   // now receive the sections
00931   //
00932   
00933   if (numSections != idData(3)) {
00934 
00935     //
00936     // we do not have correct number of sections, must delete the old and create
00937     // new ones before can recvSelf on the sections
00938     //
00939 
00940     // delete the old
00941     if (numSections != 0) {
00942       for (int i=0; i<numSections; i++)
00943         delete theSections[i];
00944       delete [] theSections;
00945     }
00946 
00947     // create a new array to hold pointers
00948     theSections = new SectionForceDeformation *[idData(3)];
00949     if (theSections == 0) {
00950       opserr << "DispBeamColumn3d::recvSelf() - out of memory creating sections array of size" <<
00951         idData(3) << endln;
00952       exit(-1);
00953     }    
00954 
00955     // create a section and recvSelf on it
00956     numSections = idData(3);
00957     loc = 0;
00958     
00959     for (i=0; i<numSections; i++) {
00960       int sectClassTag = idSections(loc);
00961       int sectDbTag = idSections(loc+1);
00962       loc += 2;
00963       theSections[i] = theBroker.getNewSection(sectClassTag);
00964       if (theSections[i] == 0) {
00965         opserr << "DispBeamColumn3d::recvSelf() - Broker could not create Section of class type" <<
00966           sectClassTag << endln;
00967         exit(-1);
00968       }
00969       theSections[i]->setDbTag(sectDbTag);
00970       if (theSections[i]->recvSelf(commitTag, theChannel, theBroker) < 0) {
00971         opserr << "DispBeamColumn3d::recvSelf() - section " <<
00972           i << "failed to recv itself\n";
00973         return -1;
00974       }     
00975     }
00976 
00977   } else {
00978 
00979     // 
00980     // for each existing section, check it is of correct type
00981     // (if not delete old & create a new one) then recvSelf on it
00982     //
00983     
00984     loc = 0;
00985     for (i=0; i<numSections; i++) {
00986       int sectClassTag = idSections(loc);
00987       int sectDbTag = idSections(loc+1);
00988       loc += 2;
00989 
00990       // check of correct type
00991       if (theSections[i]->getClassTag() !=  sectClassTag) {
00992         // delete the old section[i] and create a new one
00993         delete theSections[i];
00994         theSections[i] = theBroker.getNewSection(sectClassTag);
00995         if (theSections[i] == 0) {
00996           opserr << "DispBeamColumn3d::recvSelf() - Broker could not create Section of class type" <<
00997             sectClassTag << endln;
00998           exit(-1);
00999         }
01000       }
01001 
01002       // recvSelf on it
01003       theSections[i]->setDbTag(sectDbTag);
01004       if (theSections[i]->recvSelf(commitTag, theChannel, theBroker) < 0) {
01005         opserr << "DispBeamColumn3d::recvSelf() - section " << 
01006           i << "failed to recv itself\n";
01007         return -1;
01008       }     
01009     }
01010   }
01011 
01012   return 0;
01013 }
01014 
01015 void
01016 DispBeamColumn3d::Print(OPS_Stream &s, int flag)
01017 {
01018   s << "\nDispBeamColumn3d, element id:  " << this->getTag() << endln;
01019   s << "\tConnected external nodes:  " << connectedExternalNodes;
01020   s << "\tmass density:  " << rho << endln;
01021 
01022   double N, Mz1, Mz2, Vy, My1, My2, Vz, T;
01023   double L = crdTransf->getInitialLength();
01024   double oneOverL = 1.0/L;
01025 
01026   N   = q(0);
01027   Mz1 = q(1);
01028   Mz2 = q(2);
01029   Vy  = (Mz1+Mz2)*oneOverL;
01030   My1 = q(3);
01031   My2 = q(4);
01032   Vz  = -(My1+My2)*oneOverL;
01033   T   = q(5);
01034 
01035   s << "\tEnd 1 Forces (P Mz Vy My Vz T): "
01036     << -N+p0[0] << ' ' << Mz1 << ' ' <<  Vy+p0[1] << ' ' << My1 << ' ' <<  Vz+p0[3] << ' ' << -T << endln;
01037   s << "\tEnd 2 Forces (P Mz Vy My Vz T): "
01038     <<  N << ' ' << Mz2 << ' ' << -Vy+p0[2] << ' ' << My2 << ' ' << -Vz+p0[4] << ' ' <<  T << endln;
01039   
01040   //for (int i = 0; i < numSections; i++)
01041   //theSections[i]->Print(s,flag);
01042 }
01043 
01044 
01045 int
01046 DispBeamColumn3d::displaySelf(Renderer &theViewer, int displayMode, float fact)
01047 {
01048   // first determine the end points of the quad based on
01049   // the display factor (a measure of the distorted image)
01050   const Vector &end1Crd = theNodes[0]->getCrds();
01051   const Vector &end2Crd = theNodes[1]->getCrds();       
01052   
01053   static Vector v1(3);
01054   static Vector v2(3);
01055 
01056   if (displayMode >= 0) {
01057     const Vector &end1Disp = theNodes[0]->getDisp();
01058     const Vector &end2Disp = theNodes[1]->getDisp();
01059 
01060     for (int i = 0; i < 3; i++) {
01061       v1(i) = end1Crd(i) + end1Disp(i)*fact;
01062       v2(i) = end2Crd(i) + end2Disp(i)*fact;    
01063     }
01064   } else {
01065     int mode = displayMode * -1;
01066     const Matrix &eigen1 = theNodes[0]->getEigenvectors();
01067     const Matrix &eigen2 = theNodes[1]->getEigenvectors();
01068     if (eigen1.noCols() >= mode) {
01069       for (int i = 0; i < 3; i++) {
01070         v1(i) = end1Crd(i) + eigen1(i,mode-1)*fact;
01071         v2(i) = end2Crd(i) + eigen2(i,mode-1)*fact;    
01072       }    
01073 
01074     } else {
01075       for (int i = 0; i < 3; i++) {
01076         v1(i) = end1Crd(i);
01077         v2(i) = end2Crd(i);
01078       }    
01079     }
01080   }
01081   return theViewer.drawLine (v1, v2, 1.0, 1.0);
01082 }
01083 
01084 Response*
01085 DispBeamColumn3d::setResponse(const char **argv, int argc, Information &eleInfo, OPS_Stream &output)
01086 {
01087 
01088     Response *theResponse = 0;
01089 
01090     output.tag("ElementOutput");
01091     output.attr("eleType","DispBeamColumn2d");
01092     output.attr("eleTag",this->getTag());
01093     output.attr("node1",connectedExternalNodes[0]);
01094     output.attr("node2",connectedExternalNodes[1]);
01095 
01096     //
01097     // we compare argv[0] for known response types 
01098     //
01099 
01100     // global force - 
01101     if (strcmp(argv[0],"forces") == 0 || strcmp(argv[0],"force") == 0
01102         || strcmp(argv[0],"globalForce") == 0 || strcmp(argv[0],"globalForces") == 0) {
01103 
01104       output.tag("ResponseType","Px_1");
01105       output.tag("ResponseType","Py_1");
01106       output.tag("ResponseType","Pz_1");
01107       output.tag("ResponseType","Mx_1");
01108       output.tag("ResponseType","My_1");
01109       output.tag("ResponseType","Mz_1");
01110       output.tag("ResponseType","Px_2");
01111       output.tag("ResponseType","Py_2");
01112       output.tag("ResponseType","Pz_2");
01113       output.tag("ResponseType","Mx_2");
01114       output.tag("ResponseType","My_2");
01115       output.tag("ResponseType","Mz_2");
01116 
01117 
01118       theResponse = new ElementResponse(this, 1, P);
01119 
01120     // local force -
01121     }  else if (strcmp(argv[0],"localForce") == 0 || strcmp(argv[0],"localForces") == 0) {
01122 
01123       output.tag("ResponseType","N_ 1");
01124       output.tag("ResponseType","Vy_1");
01125       output.tag("ResponseType","Vz_1");
01126       output.tag("ResponseType","T_1");
01127       output.tag("ResponseType","My_1");
01128       output.tag("ResponseType","Tz_1");
01129       output.tag("ResponseType","N_2");
01130       output.tag("ResponseType","Py_2");
01131       output.tag("ResponseType","Pz_2");
01132       output.tag("ResponseType","T_2");
01133       output.tag("ResponseType","My_2");
01134       output.tag("ResponseType","Mz_2");
01135 
01136       theResponse = new ElementResponse(this, 2, P);
01137 
01138     // chord rotation -
01139     }  else if (strcmp(argv[0],"chordRotation") == 0 || strcmp(argv[0],"chordDeformation") == 0 
01140               || strcmp(argv[0],"basicDeformation") == 0) {
01141 
01142       output.tag("ResponseType","eps");
01143       output.tag("ResponseType","thetaZ_1");
01144       output.tag("ResponseType","thetaZ_2");
01145       output.tag("ResponseType","thetaY_1");
01146       output.tag("ResponseType","thetaY_2");
01147       output.tag("ResponseType","thetaX");
01148 
01149       theResponse = new ElementResponse(this, 3, Vector(6));
01150 
01151     // plastic rotation -
01152     } else if (strcmp(argv[0],"plasticRotation") == 0 || strcmp(argv[0],"plasticDeformation") == 0) {
01153 
01154     output.tag("ResponseType","epsP");
01155     output.tag("ResponseType","thetaZP_1");
01156     output.tag("ResponseType","thetaZP_2");
01157     output.tag("ResponseType","thetaYP_1");
01158     output.tag("ResponseType","thetaYP_2");
01159     output.tag("ResponseType","thetaXP");
01160 
01161     theResponse = new ElementResponse(this, 4, Vector(6));
01162   
01163   // section response -
01164   } else if (strcmp(argv[0],"section") ==0) { 
01165     if (argc > 2) {
01166     
01167       int sectionNum = atoi(argv[1]);
01168       if (sectionNum > 0 && sectionNum <= numSections) {
01169         
01170         output.tag("GaussPointOutput");
01171         output.attr("number",sectionNum);
01172         const Matrix &pts = quadRule.getIntegrPointCoords(numSections);
01173         output.attr("eta",2.0*pts(sectionNum-1,0)-1);
01174 
01175         theResponse =  theSections[sectionNum-1]->setResponse(&argv[2], argc-2, eleInfo, output);
01176         
01177         output.endTag();
01178       }
01179     }
01180   }
01181   
01182   output.endTag();
01183   return theResponse;
01184 }
01185 
01186 int 
01187 DispBeamColumn3d::getResponse(int responseID, Information &eleInfo)
01188 {
01189   double N, V, M1, M2, T;
01190   double L = crdTransf->getInitialLength();
01191   double oneOverL = 1.0/L;
01192 
01193   if (responseID == 1)
01194     return eleInfo.setVector(this->getResistingForce());
01195     
01196   else if (responseID == 2) {
01197     // Axial
01198     N = q(0);
01199     P(6) =  N;
01200     P(0) = -N+p0[0];
01201     
01202     // Torsion
01203     T = q(5);
01204     P(9) =  T;
01205     P(3) = -T;
01206     
01207     // Moments about z and shears along y
01208     M1 = q(1);
01209     M2 = q(2);
01210     P(5)  = M1;
01211     P(11) = M2;
01212     V = (M1+M2)*oneOverL;
01213     P(1) =  V+p0[1];
01214     P(7) = -V+p0[2];
01215     
01216     // Moments about y and shears along z
01217     M1 = q(3);
01218     M2 = q(4);
01219     P(4)  = M1;
01220     P(10) = M2;
01221     V = -(M1+M2)*oneOverL;
01222     P(2) = -V+p0[3];
01223     P(8) =  V+p0[4];
01224 
01225     return eleInfo.setVector(P);
01226   }
01227 
01228   // Chord rotation
01229   else if (responseID == 3)
01230     return eleInfo.setVector(crdTransf->getBasicTrialDisp());
01231 
01232   // Plastic rotation
01233   else if (responseID == 4) {
01234     static Vector vp(6);
01235     static Vector ve(6);
01236     const Matrix &kb = this->getInitialBasicStiff();
01237     kb.Solve(q, ve);
01238     vp = crdTransf->getBasicTrialDisp();
01239     vp -= ve;
01240     return eleInfo.setVector(vp);
01241   }
01242 
01243   else
01244     return -1;
01245 }

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