DispBeamColumn2d.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.28 $
00022 // $Date: 2006/09/05 22:59:03 $
00023 // $Source: /usr/local/cvs/OpenSees/SRC/element/dispBeamColumn/DispBeamColumn2d.cpp,v $
00024 
00025 // Written: MHS
00026 // Created: Feb 2001
00027 //
00028 // Description: This file contains the class definition for DispBeamColumn2d.
00029 
00030 #include <DispBeamColumn2d.h>
00031 #include <Node.h>
00032 #include <SectionForceDeformation.h>
00033 #include <CrdTransf2d.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 <Parameter.h>
00042 #include <Channel.h>
00043 #include <FEM_ObjectBroker.h>
00044 #include <ElementResponse.h>
00045 #include <ElementalLoad.h>
00046 
00047 Matrix DispBeamColumn2d::K(6,6);
00048 Vector DispBeamColumn2d::P(6);
00049 double DispBeamColumn2d::workArea[100];
00050 
00051 DispBeamColumn2d::DispBeamColumn2d(int tag, int nd1, int nd2,
00052                                    int numSec, SectionForceDeformation **s,
00053                                    BeamIntegration& bi,
00054                                    CrdTransf2d &coordTransf, double r)
00055 :Element (tag, ELE_TAG_DispBeamColumn2d), 
00056  numSections(numSec), theSections(0), crdTransf(0), beamInt(0),
00057   connectedExternalNodes(2),
00058   Q(6), q(3), rho(r)
00059 {
00060   // Allocate arrays of pointers to SectionForceDeformations
00061   theSections = new SectionForceDeformation *[numSections];
00062     
00063   if (theSections == 0) {
00064     opserr << "DispBeamColumn2d::DispBeamColumn2d - failed to allocate section model pointer\n";
00065     exit(-1);
00066   }
00067 
00068   for (int i = 0; i < numSections; i++) {
00069     
00070     // Get copies of the material model for each integration point
00071     theSections[i] = s[i]->getCopy();
00072     
00073     // Check allocation
00074     if (theSections[i] == 0) {
00075       opserr << "DispBeamColumn2d::DispBeamColumn2d -- failed to get a copy of section model\n";
00076       exit(-1);
00077     }
00078   }
00079   
00080   beamInt = bi.getCopy();
00081   
00082   if (beamInt == 0) {
00083     opserr << "DispBeamColumn2d::DispBeamColumn2d - failed to copy beam integration\n";
00084     exit(-1);
00085   }
00086 
00087   crdTransf = coordTransf.getCopy();
00088   
00089   if (crdTransf == 0) {
00090     opserr << "DispBeamColumn2d::DispBeamColumn2d - failed to copy coordinate transformation\n";
00091     exit(-1);
00092   }
00093   
00094   // Set connected external node IDs
00095   connectedExternalNodes(0) = nd1;
00096   connectedExternalNodes(1) = nd2;
00097 
00098   theNodes[0] = 0;
00099   theNodes[1] = 0;
00100   
00101   q0[0] = 0.0;
00102   q0[1] = 0.0;
00103   q0[2] = 0.0;
00104   
00105   p0[0] = 0.0;
00106   p0[1] = 0.0;
00107   p0[2] = 0.0;
00108   
00109 // AddingSensitivity:BEGIN /////////////////////////////////////
00110         parameterID = 0;
00111 // AddingSensitivity:END //////////////////////////////////////
00112 }
00113 
00114 DispBeamColumn2d::DispBeamColumn2d()
00115 :Element (0, ELE_TAG_DispBeamColumn2d),
00116  numSections(0), theSections(0), crdTransf(0), beamInt(0),
00117  connectedExternalNodes(2),
00118   Q(6), q(3), rho(0.0)
00119 {
00120     q0[0] = 0.0;
00121     q0[1] = 0.0;
00122     q0[2] = 0.0;
00123 
00124     p0[0] = 0.0;
00125     p0[1] = 0.0;
00126     p0[2] = 0.0;
00127 
00128     theNodes[0] = 0;
00129     theNodes[1] = 0;
00130 
00131 // AddingSensitivity:BEGIN /////////////////////////////////////
00132         parameterID = 0;
00133 // AddingSensitivity:END //////////////////////////////////////
00134 }
00135 
00136 DispBeamColumn2d::~DispBeamColumn2d()
00137 {    
00138   for (int i = 0; i < numSections; i++) {
00139     if (theSections[i])
00140       delete theSections[i];
00141   }
00142   
00143   // Delete the array of pointers to SectionForceDeformation pointer arrays
00144   if (theSections)
00145     delete [] theSections;
00146   
00147   if (crdTransf)
00148     delete crdTransf;
00149 
00150   if (beamInt != 0)
00151     delete beamInt;
00152 }
00153 
00154 int
00155 DispBeamColumn2d::getNumExternalNodes() const
00156 {
00157     return 2;
00158 }
00159 
00160 const ID&
00161 DispBeamColumn2d::getExternalNodes()
00162 {
00163     return connectedExternalNodes;
00164 }
00165 
00166 Node **
00167 DispBeamColumn2d::getNodePtrs()
00168 {
00169     return theNodes;
00170 }
00171 
00172 int
00173 DispBeamColumn2d::getNumDOF()
00174 {
00175     return 6;
00176 }
00177 
00178 void
00179 DispBeamColumn2d::setDomain(Domain *theDomain)
00180 {
00181         // Check Domain is not null - invoked when object removed from a domain
00182     if (theDomain == 0) {
00183         theNodes[0] = 0;
00184         theNodes[1] = 0;
00185         return;
00186     }
00187 
00188     int Nd1 = connectedExternalNodes(0);
00189     int Nd2 = connectedExternalNodes(1);
00190 
00191     theNodes[0] = theDomain->getNode(Nd1);
00192     theNodes[1] = theDomain->getNode(Nd2);
00193 
00194     if (theNodes[0] == 0 || theNodes[1] == 0) {
00195         //opserr << "FATAL ERROR DispBeamColumn2d (tag: %d), node not found in domain",
00196         //      this->getTag());
00197         
00198         return;
00199     }
00200 
00201     int dofNd1 = theNodes[0]->getNumberDOF();
00202     int dofNd2 = theNodes[1]->getNumberDOF();
00203     
00204     if (dofNd1 != 3 || dofNd2 != 3) {
00205         //opserr << "FATAL ERROR DispBeamColumn2d (tag: %d), has differing number of DOFs at its nodes",
00206         //      this->getTag());
00207         
00208         return;
00209     }
00210 
00211         if (crdTransf->initialize(theNodes[0], theNodes[1])) {
00212                 // Add some error check
00213         }
00214 
00215         double L = crdTransf->getInitialLength();
00216 
00217         if (L == 0.0) {
00218                 // Add some error check
00219         }
00220 
00221     this->DomainComponent::setDomain(theDomain);
00222 
00223         this->update();
00224 }
00225 
00226 int
00227 DispBeamColumn2d::commitState()
00228 {
00229     int retVal = 0;
00230 
00231     // call element commitState to do any base class stuff
00232     if ((retVal = this->Element::commitState()) != 0) {
00233       opserr << "DispBeamColumn2d::commitState () - failed in base class";
00234     }    
00235 
00236     // Loop over the integration points and commit the material states
00237     for (int i = 0; i < numSections; i++)
00238                 retVal += theSections[i]->commitState();
00239 
00240     retVal += crdTransf->commitState();
00241 
00242     return retVal;
00243 }
00244 
00245 int
00246 DispBeamColumn2d::revertToLastCommit()
00247 {
00248     int retVal = 0;
00249 
00250     // Loop over the integration points and revert to last committed state
00251     for (int i = 0; i < numSections; i++)
00252                 retVal += theSections[i]->revertToLastCommit();
00253 
00254     retVal += crdTransf->revertToLastCommit();
00255 
00256     return retVal;
00257 }
00258 
00259 int
00260 DispBeamColumn2d::revertToStart()
00261 {
00262     int retVal = 0;
00263 
00264     // Loop over the integration points and revert states to start
00265     for (int i = 0; i < numSections; i++)
00266                 retVal += theSections[i]->revertToStart();
00267 
00268     retVal += crdTransf->revertToStart();
00269 
00270     return retVal;
00271 }
00272 
00273 int
00274 DispBeamColumn2d::update(void)
00275 {
00276   // Update the transformation
00277   crdTransf->update();
00278   
00279   // Get basic deformations
00280   const Vector &v = crdTransf->getBasicTrialDisp();
00281   
00282   double L = crdTransf->getInitialLength();
00283   double oneOverL = 1.0/L;
00284 
00285   //const Matrix &pts = quadRule.getIntegrPointCoords(numSections);
00286   double xi[10];
00287   beamInt->getSectionLocations(numSections, L, xi);
00288   
00289   // Loop over the integration points
00290   for (int i = 0; i < numSections; i++) {
00291     
00292     int order = theSections[i]->getOrder();
00293     const ID &code = theSections[i]->getType();
00294     
00295     Vector e(workArea, order);
00296     
00297     //double xi6 = 6.0*pts(i,0);
00298     double xi6 = 6.0*xi[i];
00299     
00300     int j;
00301     for (j = 0; j < order; j++) {
00302       switch(code(j)) {
00303       case SECTION_RESPONSE_P:
00304         e(j) = oneOverL*v(0); break;
00305       case SECTION_RESPONSE_MZ:
00306         e(j) = oneOverL*((xi6-4.0)*v(1) + (xi6-2.0)*v(2)); break;
00307       default:
00308         e(j) = 0.0; break;
00309       }
00310     }
00311     
00312     // Set the section deformations
00313     theSections[i]->setTrialSectionDeformation(e);
00314   }
00315   
00316   return 0;
00317 }
00318 
00319 const Matrix&
00320 DispBeamColumn2d::getTangentStiff()
00321 {
00322   static Matrix kb(3,3);
00323 
00324   // Zero for integral
00325   kb.Zero();
00326   q.Zero();
00327   
00328   double L = crdTransf->getInitialLength();
00329   double oneOverL = 1.0/L;
00330   
00331   //const Matrix &pts = quadRule.getIntegrPointCoords(numSections);
00332   //const Vector &wts = quadRule.getIntegrPointWeights(numSections);
00333   double xi[10];
00334   beamInt->getSectionLocations(numSections, L, xi);
00335   double wt[10];
00336   beamInt->getSectionWeights(numSections, L, wt);
00337 
00338   // Loop over the integration points
00339   for (int i = 0; i < numSections; i++) {
00340     
00341     int order = theSections[i]->getOrder();
00342     const ID &code = theSections[i]->getType();
00343 
00344     Matrix ka(workArea, order, 3);
00345     ka.Zero();
00346 
00347     //double xi6 = 6.0*pts(i,0);
00348     double xi6 = 6.0*xi[i];
00349 
00350     // Get the section tangent stiffness and stress resultant
00351     const Matrix &ks = theSections[i]->getSectionTangent();
00352     const Vector &s = theSections[i]->getStressResultant();
00353         
00354     // Perform numerical integration
00355     //kb.addMatrixTripleProduct(1.0, *B, ks, wts(i)/L);
00356     //double wti = wts(i)*oneOverL;
00357     double wti = wt[i]*oneOverL;
00358     double tmp;
00359     int j, k;
00360     for (j = 0; j < order; j++) {
00361       switch(code(j)) {
00362       case SECTION_RESPONSE_P:
00363         for (k = 0; k < order; k++)
00364           ka(k,0) += ks(k,j)*wti;
00365         break;
00366       case SECTION_RESPONSE_MZ:
00367         for (k = 0; k < order; k++) {
00368           tmp = ks(k,j)*wti;
00369           ka(k,1) += (xi6-4.0)*tmp;
00370           ka(k,2) += (xi6-2.0)*tmp;
00371         }
00372         break;
00373       default:
00374         break;
00375       }
00376     }
00377     for (j = 0; j < order; j++) {
00378       switch (code(j)) {
00379       case SECTION_RESPONSE_P:
00380         for (k = 0; k < 3; k++)
00381           kb(0,k) += ka(j,k);
00382         break;
00383       case SECTION_RESPONSE_MZ:
00384         for (k = 0; k < 3; k++) {
00385           tmp = ka(j,k);
00386           kb(1,k) += (xi6-4.0)*tmp;
00387           kb(2,k) += (xi6-2.0)*tmp;
00388         }
00389         break;
00390       default:
00391         break;
00392       }
00393     }
00394     
00395     //q.addMatrixTransposeVector(1.0, *B, s, wts(i));
00396     double si;
00397     for (j = 0; j < order; j++) {
00398       //si = s(j)*wts(i);
00399       si = s(j)*wt[i];
00400       switch(code(j)) {
00401       case SECTION_RESPONSE_P:
00402         q(0) += si; break;
00403       case SECTION_RESPONSE_MZ:
00404         q(1) += (xi6-4.0)*si; q(2) += (xi6-2.0)*si; break;
00405       default:
00406         break;
00407       }
00408     }
00409     
00410   }
00411   
00412   // Add effects of element loads, q = q(v) + q0
00413   q(0) += q0[0];
00414   q(1) += q0[1];
00415   q(2) += q0[2];
00416 
00417   // Transform to global stiffness
00418   K = crdTransf->getGlobalStiffMatrix(kb, q);
00419 
00420   return K;
00421 }
00422 
00423 const Matrix&
00424 DispBeamColumn2d::getInitialBasicStiff()
00425 {
00426   static Matrix kb(3,3);
00427 
00428   // Zero for integral
00429   kb.Zero();
00430   
00431   double L = crdTransf->getInitialLength();
00432   double oneOverL = 1.0/L;
00433   
00434   //const Matrix &pts = quadRule.getIntegrPointCoords(numSections);
00435   //const Vector &wts = quadRule.getIntegrPointWeights(numSections);
00436   double xi[10];
00437   beamInt->getSectionLocations(numSections, L, xi);
00438   double wt[10];
00439   beamInt->getSectionWeights(numSections, L, wt);
00440 
00441   // Loop over the integration points
00442   for (int i = 0; i < numSections; i++) {
00443     
00444     int order = theSections[i]->getOrder();
00445     const ID &code = theSections[i]->getType();
00446   
00447     Matrix ka(workArea, order, 3);
00448     ka.Zero();
00449 
00450     //double xi6 = 6.0*pts(i,0);
00451     double xi6 = 6.0*xi[i];
00452     
00453     // Get the section tangent stiffness and stress resultant
00454     const Matrix &ks = theSections[i]->getInitialTangent();
00455     
00456     // Perform numerical integration
00457     //kb.addMatrixTripleProduct(1.0, *B, ks, wts(i)/L);
00458     //double wti = wts(i)*oneOverL;
00459     double wti = wt[i]*oneOverL;
00460     double tmp;
00461     int j, k;
00462     for (j = 0; j < order; j++) {
00463       switch(code(j)) {
00464       case SECTION_RESPONSE_P:
00465         for (k = 0; k < order; k++)
00466           ka(k,0) += ks(k,j)*wti;
00467         break;
00468       case SECTION_RESPONSE_MZ:
00469         for (k = 0; k < order; k++) {
00470           tmp = ks(k,j)*wti;
00471           ka(k,1) += (xi6-4.0)*tmp;
00472           ka(k,2) += (xi6-2.0)*tmp;
00473         }
00474         break;
00475       default:
00476         break;
00477       }
00478     }
00479     for (j = 0; j < order; j++) {
00480       switch (code(j)) {
00481       case SECTION_RESPONSE_P:
00482         for (k = 0; k < 3; k++)
00483           kb(0,k) += ka(j,k);
00484         break;
00485       case SECTION_RESPONSE_MZ:
00486         for (k = 0; k < 3; k++) {
00487           tmp = ka(j,k);
00488           kb(1,k) += (xi6-4.0)*tmp;
00489           kb(2,k) += (xi6-2.0)*tmp;
00490         }
00491         break;
00492       default:
00493         break;
00494       }
00495     }
00496     
00497   }
00498 
00499   return kb;
00500 }
00501 
00502 const Matrix&
00503 DispBeamColumn2d::getInitialStiff()
00504 {
00505   const Matrix &kb = this->getInitialBasicStiff();
00506 
00507   // Transform to global stiffness
00508   K = crdTransf->getInitialGlobalStiffMatrix(kb);
00509 
00510   return K;
00511 }
00512 
00513 const Matrix&
00514 DispBeamColumn2d::getMass()
00515 {
00516   K.Zero();
00517 
00518   if (rho == 0.0)
00519     return K;
00520   
00521   double L = crdTransf->getInitialLength();
00522   double m = 0.5*rho*L;
00523   
00524   K(0,0) = K(1,1) = K(3,3) = K(4,4) = m;
00525   
00526   return K;
00527 }
00528 
00529 void
00530 DispBeamColumn2d::zeroLoad(void)
00531 {
00532   Q.Zero();
00533 
00534   q0[0] = 0.0;
00535   q0[1] = 0.0;
00536   q0[2] = 0.0;
00537   
00538   p0[0] = 0.0;
00539   p0[1] = 0.0;
00540   p0[2] = 0.0;
00541   
00542   return;
00543 }
00544 
00545 int 
00546 DispBeamColumn2d::addLoad(ElementalLoad *theLoad, double loadFactor)
00547 {
00548   int type;
00549   const Vector &data = theLoad->getData(type, loadFactor);
00550   double L = crdTransf->getInitialLength();
00551   
00552   if (type == LOAD_TAG_Beam2dUniformLoad) {
00553     double wt = data(0)*loadFactor;  // Transverse (+ve upward)
00554     double wa = data(1)*loadFactor;  // Axial (+ve from node I to J)
00555 
00556     double V = 0.5*wt*L;
00557     double M = V*L/6.0; // wt*L*L/12
00558     double P = wa*L;
00559 
00560     // Reactions in basic system
00561     p0[0] -= P;
00562     p0[1] -= V;
00563     p0[2] -= V;
00564 
00565     // Fixed end forces in basic system
00566     q0[0] -= 0.5*P;
00567     q0[1] -= M;
00568     q0[2] += M;
00569   }
00570   else if (type == LOAD_TAG_Beam2dPointLoad) {
00571     double P = data(0)*loadFactor;
00572     double N = data(1)*loadFactor;
00573     double aOverL = data(2);
00574 
00575     if (aOverL < 0.0 || aOverL > 1.0)
00576       return 0;
00577 
00578     double a = aOverL*L;
00579     double b = L-a;
00580 
00581     // Reactions in basic system
00582     p0[0] -= N;
00583     double V1 = P*(1.0-aOverL);
00584     double V2 = P*aOverL;
00585     p0[1] -= V1;
00586     p0[2] -= V2;
00587 
00588     double L2 = 1.0/(L*L);
00589     double a2 = a*a;
00590     double b2 = b*b;
00591 
00592     // Fixed end forces in basic system
00593     q0[0] -= N*aOverL;
00594     double M1 = -a * b2 * P * L2;
00595     double M2 = a2 * b * P * L2;
00596     q0[1] += M1;
00597     q0[2] += M2;
00598   }
00599   else {
00600     opserr << "DispBeamColumn2d::DispBeamColumn2d -- load type unknown for element with tag: "
00601            << this->getTag() << "DispBeamColumn2d::addLoad()\n"; 
00602                             
00603     return -1;
00604   }
00605 
00606   return 0;
00607 }
00608 
00609 int 
00610 DispBeamColumn2d::addInertiaLoadToUnbalance(const Vector &accel)
00611 {
00612         // Check for a quick return
00613         if (rho == 0.0) 
00614                 return 0;
00615 
00616         // Get R * accel from the nodes
00617         const Vector &Raccel1 = theNodes[0]->getRV(accel);
00618         const Vector &Raccel2 = theNodes[1]->getRV(accel);
00619 
00620     if (3 != Raccel1.Size() || 3 != Raccel2.Size()) {
00621       opserr << "DispBeamColumn2d::addInertiaLoadToUnbalance matrix and vector sizes are incompatable\n";
00622       return -1;
00623     }
00624 
00625         double L = crdTransf->getInitialLength();
00626         double m = 0.5*rho*L;
00627 
00628     // Want to add ( - fact * M R * accel ) to unbalance
00629         // Take advantage of lumped mass matrix
00630         Q(0) -= m*Raccel1(0);
00631         Q(1) -= m*Raccel1(1);
00632         Q(3) -= m*Raccel2(0);
00633         Q(4) -= m*Raccel2(1);
00634 
00635     return 0;
00636 }
00637 
00638 const Vector&
00639 DispBeamColumn2d::getResistingForce()
00640 {
00641   double L = crdTransf->getInitialLength();
00642   double oneOverL = 1.0/L;
00643   
00644   //const Matrix &pts = quadRule.getIntegrPointCoords(numSections);
00645   //const Vector &wts = quadRule.getIntegrPointWeights(numSections);  
00646   double xi[10];
00647   beamInt->getSectionLocations(numSections, L, xi);
00648   double wt[10];
00649   beamInt->getSectionWeights(numSections, L, wt);
00650 
00651   // Zero for integration
00652   q.Zero();
00653   
00654   // Loop over the integration points
00655   for (int i = 0; i < numSections; i++) {
00656     
00657     int order = theSections[i]->getOrder();
00658     const ID &code = theSections[i]->getType();
00659   
00660     //double xi6 = 6.0*pts(i,0);
00661     double xi6 = 6.0*xi[i];
00662     
00663     // Get section stress resultant
00664     const Vector &s = theSections[i]->getStressResultant();
00665     
00666     // Perform numerical integration on internal force
00667     //q.addMatrixTransposeVector(1.0, *B, s, wts(i));
00668     
00669     double si;
00670     for (int j = 0; j < order; j++) {
00671       //si = s(j)*wts(i);
00672       si = s(j)*wt[i];
00673       switch(code(j)) {
00674       case SECTION_RESPONSE_P:
00675         q(0) += si; break;
00676       case SECTION_RESPONSE_MZ:
00677         q(1) += (xi6-4.0)*si; q(2) += (xi6-2.0)*si; break;
00678       default:
00679         break;
00680       }
00681     }
00682     
00683   }
00684   
00685   // Add effects of element loads, q = q(v) + q0
00686   q(0) += q0[0];
00687   q(1) += q0[1];
00688   q(2) += q0[2];
00689 
00690   // Vector for reactions in basic system
00691   Vector p0Vec(p0, 3);
00692 
00693   P = crdTransf->getGlobalResistingForce(q, p0Vec);
00694   
00695   // Subtract other external nodal loads ... P_res = P_int - P_ext
00696   //P.addVector(1.0, Q, -1.0);
00697   P(0) -= Q(0);
00698   P(1) -= Q(1);
00699   P(2) -= Q(2);
00700   P(3) -= Q(3);
00701   P(4) -= Q(4);
00702   P(5) -= Q(5);
00703   
00704   return P;
00705 }
00706 
00707 const Vector&
00708 DispBeamColumn2d::getResistingForceIncInertia()
00709 {
00710 
00711   this->getResistingForce();
00712   
00713   if (rho != 0.0) {
00714     const Vector &accel1 = theNodes[0]->getTrialAccel();
00715     const Vector &accel2 = theNodes[1]->getTrialAccel();
00716     
00717     // Compute the current resisting force
00718     this->getResistingForce();
00719     
00720     double L = crdTransf->getInitialLength();
00721     double m = 0.5*rho*L;
00722     
00723     P(0) += m*accel1(0);
00724     P(1) += m*accel1(1);
00725     P(3) += m*accel2(0);
00726     P(4) += m*accel2(1);
00727     
00728     // add the damping forces if rayleigh damping
00729     if (alphaM != 0.0 || betaK != 0.0 || betaK0 != 0.0 || betaKc != 0.0)
00730       P += this->getRayleighDampingForces();
00731 
00732   } else {
00733     
00734     // add the damping forces if rayleigh damping
00735     if (betaK != 0.0 || betaK0 != 0.0 || betaKc != 0.0)
00736       P += this->getRayleighDampingForces();
00737   }
00738 
00739   return P;
00740 }
00741 
00742 int
00743 DispBeamColumn2d::sendSelf(int commitTag, Channel &theChannel)
00744 {
00745   // place the integer data into an ID
00746 
00747   int dbTag = this->getDbTag();
00748   int i, j;
00749   int loc = 0;
00750   
00751   static ID idData(7);  // one bigger than needed so no clash later
00752   idData(0) = this->getTag();
00753   idData(1) = connectedExternalNodes(0);
00754   idData(2) = connectedExternalNodes(1);
00755   idData(3) = numSections;
00756   idData(4) = crdTransf->getClassTag();
00757   int crdTransfDbTag  = crdTransf->getDbTag();
00758   if (crdTransfDbTag  == 0) {
00759     crdTransfDbTag = theChannel.getDbTag();
00760     if (crdTransfDbTag  != 0) 
00761       crdTransf->setDbTag(crdTransfDbTag);
00762   }
00763   idData(5) = crdTransfDbTag;
00764   
00765   if (theChannel.sendID(dbTag, commitTag, idData) < 0) {
00766     opserr << "DispBeamColumn2d::sendSelf() - failed to send ID data\n";
00767      return -1;
00768   }    
00769 
00770   // send the coordinate transformation
00771   
00772   if (crdTransf->sendSelf(commitTag, theChannel) < 0) {
00773      opserr << "DispBeamColumn2d::sendSelf() - failed to send crdTranf\n";
00774      return -1;
00775   }      
00776 
00777   
00778   //
00779   // send an ID for the sections containing each sections dbTag and classTag
00780   // if section ha no dbTag get one and assign it
00781   //
00782 
00783   ID idSections(2*numSections);
00784   loc = 0;
00785   for (i = 0; i<numSections; i++) {
00786     int sectClassTag = theSections[i]->getClassTag();
00787     int sectDbTag = theSections[i]->getDbTag();
00788     if (sectDbTag == 0) {
00789       sectDbTag = theChannel.getDbTag();
00790       theSections[i]->setDbTag(sectDbTag);
00791     }
00792 
00793     idSections(loc) = sectClassTag;
00794     idSections(loc+1) = sectDbTag;
00795     loc += 2;
00796   }
00797 
00798   if (theChannel.sendID(dbTag, commitTag, idSections) < 0)  {
00799     opserr << "DispBeamColumn2d::sendSelf() - failed to send ID data\n";
00800     return -1;
00801   }    
00802 
00803   //
00804   // send the sections
00805   //
00806   
00807   for (j = 0; j<numSections; j++) {
00808     if (theSections[j]->sendSelf(commitTag, theChannel) < 0) {
00809       opserr << "DispBeamColumn2d::sendSelf() - section " << 
00810         j << "failed to send itself\n";
00811       return -1;
00812     }
00813   }
00814 
00815   return 0;
00816 }
00817 
00818 int
00819 DispBeamColumn2d::recvSelf(int commitTag, Channel &theChannel,
00820                            FEM_ObjectBroker &theBroker)
00821 {
00822   //
00823   // receive the integer data containing tag, numSections and coord transformation info
00824   //
00825   int dbTag = this->getDbTag();
00826   int i;
00827   
00828   static ID idData(7); // one bigger than needed so no clash with section ID
00829 
00830   if (theChannel.recvID(dbTag, commitTag, idData) < 0)  {
00831     opserr << "DispBeamColumn2d::recvSelf() - failed to recv ID data\n";
00832     return -1;
00833   }    
00834 
00835   this->setTag(idData(0));
00836   connectedExternalNodes(0) = idData(1);
00837   connectedExternalNodes(1) = idData(2);
00838   
00839   int crdTransfClassTag = idData(4);
00840   int crdTransfDbTag = idData(5);
00841 
00842   // create a new crdTransf object if one needed
00843   if (crdTransf == 0 || crdTransf->getClassTag() != crdTransfClassTag) {
00844       if (crdTransf != 0)
00845           delete crdTransf;
00846 
00847       crdTransf = theBroker.getNewCrdTransf2d(crdTransfClassTag);
00848 
00849       if (crdTransf == 0) {
00850         opserr << "DispBeamColumn2d::recvSelf() - failed to obtain a CrdTrans object with classTag " <<
00851           crdTransfClassTag << endln;
00852           return -2;      
00853       }
00854   }
00855 
00856   crdTransf->setDbTag(crdTransfDbTag);
00857 
00858   // invoke recvSelf on the crdTransf object
00859   if (crdTransf->recvSelf(commitTag, theChannel, theBroker) < 0) {
00860     opserr << "DispBeamColumn2d::sendSelf() - failed to recv crdTranf\n";
00861     return -3;
00862   }      
00863   
00864   //
00865   // recv an ID for the sections containing each sections dbTag and classTag
00866   //
00867 
00868   ID idSections(2*idData(3));
00869   int loc = 0;
00870 
00871   if (theChannel.recvID(dbTag, commitTag, idSections) < 0)  {
00872     opserr << "DispBeamColumn2d::recvSelf() - failed to recv ID data\n";
00873     return -1;
00874   }    
00875 
00876   //
00877   // now receive the sections
00878   //
00879   
00880   if (numSections != idData(3)) {
00881 
00882     //
00883     // we do not have correct number of sections, must delete the old and create
00884     // new ones before can recvSelf on the sections
00885     //
00886 
00887     // delete the old
00888     if (numSections != 0) {
00889       for (int i=0; i<numSections; i++)
00890         delete theSections[i];
00891       delete [] theSections;
00892     }
00893 
00894     // create a new array to hold pointers
00895     theSections = new SectionForceDeformation *[idData(3)];
00896     if (theSections == 0) {
00897 opserr << "DispBeamColumn2d::recvSelf() - out of memory creating sections array of size " <<
00898   idData(3) << endln;
00899       return -1;
00900     }    
00901 
00902     // create a section and recvSelf on it
00903     numSections = idData(3);
00904     loc = 0;
00905     
00906     for (i=0; i<numSections; i++) {
00907       int sectClassTag = idSections(loc);
00908       int sectDbTag = idSections(loc+1);
00909       loc += 2;
00910       theSections[i] = theBroker.getNewSection(sectClassTag);
00911       if (theSections[i] == 0) {
00912         opserr << "DispBeamColumn2d::recvSelf() - Broker could not create Section of class type " <<
00913           sectClassTag << endln;
00914         exit(-1);
00915       }
00916       theSections[i]->setDbTag(sectDbTag);
00917       if (theSections[i]->recvSelf(commitTag, theChannel, theBroker) < 0) {
00918         opserr << "DispBeamColumn2d::recvSelf() - section " << i << " failed to recv itself\n";
00919         return -1;
00920       }     
00921     }
00922 
00923   } else {
00924 
00925     // 
00926     // for each existing section, check it is of correct type
00927     // (if not delete old & create a new one) then recvSelf on it
00928     //
00929     
00930     loc = 0;
00931     for (i=0; i<numSections; i++) {
00932       int sectClassTag = idSections(loc);
00933       int sectDbTag = idSections(loc+1);
00934       loc += 2;
00935 
00936       // check of correct type
00937       if (theSections[i]->getClassTag() !=  sectClassTag) {
00938         // delete the old section[i] and create a new one
00939         delete theSections[i];
00940         theSections[i] = theBroker.getNewSection(sectClassTag);
00941         if (theSections[i] == 0) {
00942         opserr << "DispBeamColumn2d::recvSelf() - Broker could not create Section of class type " <<
00943           sectClassTag << endln;
00944         exit(-1);
00945         }
00946       }
00947 
00948       // recvSelf on it
00949       theSections[i]->setDbTag(sectDbTag);
00950       if (theSections[i]->recvSelf(commitTag, theChannel, theBroker) < 0) {
00951         opserr << "DispBeamColumn2d::recvSelf() - section " << i << " failed to recv itself\n";
00952         return -1;
00953       }     
00954     }
00955   }
00956 
00957   return 0;
00958 }
00959 
00960 void
00961 DispBeamColumn2d::Print(OPS_Stream &s, int flag)
00962 {
00963   s << "\nDispBeamColumn2d, element id:  " << this->getTag() << endln;
00964   s << "\tConnected external nodes:  " << connectedExternalNodes;
00965   s << "\tCoordTransf: " << crdTransf->getTag() << endln;
00966   s << "\tmass density:  " << rho << endln;
00967   
00968   double L = crdTransf->getInitialLength();
00969   double P  = q(0);
00970   double M1 = q(1);
00971   double M2 = q(2);
00972   double V = (M1+M2)/L;
00973   s << "\tEnd 1 Forces (P V M): " << -P+p0[0]
00974     << " " << V+p0[1] << " " << M1 << endln;
00975   s << "\tEnd 2 Forces (P V M): " << P
00976     << " " << -V+p0[2] << " " << M2 << endln;
00977 
00978   beamInt->Print(s, flag);
00979 
00980   for (int i = 0; i < numSections; i++)
00981     theSections[i]->Print(s,flag);
00982 }
00983 
00984 
00985 int
00986 DispBeamColumn2d::displaySelf(Renderer &theViewer, int displayMode, float fact)
00987 {
00988     // first determine the end points of the quad based on
00989     // the display factor (a measure of the distorted image)
00990     const Vector &end1Crd = theNodes[0]->getCrds();
00991     const Vector &end2Crd = theNodes[1]->getCrds();     
00992 
00993   static Vector v1(3);
00994   static Vector v2(3);
00995 
00996   if (displayMode >= 0) {
00997     const Vector &end1Disp = theNodes[0]->getDisp();
00998     const Vector &end2Disp = theNodes[1]->getDisp();
00999     
01000     for (int i = 0; i < 2; i++) {
01001       v1(i) = end1Crd(i) + end1Disp(i)*fact;
01002       v2(i) = end2Crd(i) + end2Disp(i)*fact;    
01003     }
01004   } else {
01005     int mode = displayMode  *  -1;
01006     const Matrix &eigen1 = theNodes[0]->getEigenvectors();
01007     const Matrix &eigen2 = theNodes[1]->getEigenvectors();
01008     if (eigen1.noCols() >= mode) {
01009       for (int i = 0; i < 2; i++) {
01010         v1(i) = end1Crd(i) + eigen1(i,mode-1)*fact;
01011         v2(i) = end2Crd(i) + eigen2(i,mode-1)*fact;    
01012       }    
01013     } else {
01014       for (int i = 0; i < 2; i++) {
01015         v1(i) = end1Crd(i);
01016         v2(i) = end2Crd(i);
01017       }    
01018     }
01019   }
01020         
01021   return theViewer.drawLine (v1, v2, 1.0, 1.0);
01022 }
01023 
01024 Response*
01025 DispBeamColumn2d::setResponse(const char **argv, int argc,
01026                               Information &eleInfo, OPS_Stream &output)
01027 {
01028   Response *theResponse = 0;
01029 
01030   output.tag("ElementOutput");
01031   output.attr("eleType","DispBeamColumn2d");
01032   output.attr("eleTag",this->getTag());
01033   output.attr("node1",connectedExternalNodes[0]);
01034   output.attr("node2",connectedExternalNodes[1]);
01035 
01036   // global force - 
01037   if (strcmp(argv[0],"forces") == 0 || strcmp(argv[0],"force") == 0
01038       || strcmp(argv[0],"globalForce") == 0 || strcmp(argv[0],"globalForces") == 0) {
01039 
01040     output.tag("ResponseType","Px_1");
01041     output.tag("ResponseType","Py_1");
01042     output.tag("ResponseType","Mz_1");
01043     output.tag("ResponseType","Px_2");
01044     output.tag("ResponseType","Py_2");
01045     output.tag("ResponseType","Mz_2");
01046 
01047     theResponse =  new ElementResponse(this, 1, P);
01048   
01049   
01050   // local force -
01051   } else if (strcmp(argv[0],"localForce") == 0 || strcmp(argv[0],"localForces") == 0) {
01052 
01053     output.tag("ResponseType","N1");
01054     output.tag("ResponseType","V1");
01055     output.tag("ResponseType","M1");
01056     output.tag("ResponseType","N2");
01057     output.tag("ResponseType","V2");
01058     output.tag("ResponseType","M2");
01059 
01060     theResponse =  new ElementResponse(this, 2, P);
01061   
01062 
01063   // basic force -
01064   } else if (strcmp(argv[0],"basicForce") == 0 || strcmp(argv[0],"basicForces") == 0) {
01065 
01066     output.tag("ResponseType","N");
01067     output.tag("ResponseType","M1");
01068     output.tag("ResponseType","M2");
01069 
01070     theResponse =  new ElementResponse(this, 9, Vector(3));
01071 
01072   // chord rotation -
01073   } else if (strcmp(argv[0],"chordRotation") == 0 || strcmp(argv[0],"chordDeformation") == 0 
01074              || strcmp(argv[0],"basicDeformation") == 0) {
01075 
01076     output.tag("ResponseType","eps");
01077     output.tag("ResponseType","theta1");
01078     output.tag("ResponseType","theta2");
01079 
01080     theResponse =  new ElementResponse(this, 3, Vector(3));
01081   
01082   // plastic rotation -
01083   } else if (strcmp(argv[0],"plasticRotation") == 0 || strcmp(argv[0],"plasticDeformation") == 0) {
01084 
01085     output.tag("ResponseType","epsP");
01086     output.tag("ResponseType","theta1P");
01087     output.tag("ResponseType","theta2P");
01088 
01089     theResponse =  new ElementResponse(this, 4, Vector(3));
01090 
01091   // section response -
01092   } else if (strstr(argv[0],"section") != 0) {
01093     if (argc > 2) {
01094       int sectionNum = atoi(argv[1]);
01095       if (sectionNum > 0 && sectionNum <= numSections) {
01096 
01097         output.tag("GaussPointOutput");
01098         output.attr("number",sectionNum);
01099         double xi[10];
01100         double L = crdTransf->getInitialLength();
01101         beamInt->getSectionLocations(numSections, L, xi);
01102         output.attr("eta",xi[sectionNum-1]*L);
01103 
01104         theResponse = theSections[sectionNum-1]->setResponse(&argv[2], argc-2, eleInfo, output);
01105         
01106         output.endTag();
01107       }
01108     }
01109   }
01110   
01111   // curvature sensitivity along element length
01112   else if (strcmp(argv[0],"dcurvdh") == 0)
01113     return new ElementResponse(this, 5, Vector(numSections));
01114   
01115   // basic deformation sensitivity
01116   else if (strcmp(argv[0],"dvdh") == 0)
01117     return new ElementResponse(this, 6, Vector(3));
01118   
01119   else if (strcmp(argv[0],"integrationPoints") == 0)
01120     return new ElementResponse(this, 7, Vector(numSections));
01121   
01122   else if (strcmp(argv[0],"integrationWeights") == 0)
01123     return new ElementResponse(this, 8, Vector(numSections));
01124   
01125   output.endTag();
01126   return theResponse;
01127 }
01128 
01129 int 
01130 DispBeamColumn2d::getResponse(int responseID, Information &eleInfo)
01131 {
01132   double V;
01133   double L = crdTransf->getInitialLength();
01134 
01135   if (responseID == 1)
01136     return eleInfo.setVector(this->getResistingForce());
01137 
01138   else if (responseID == 2) {
01139       P(3) =  q(0);
01140       P(0) = -q(0)+p0[0];
01141       P(2) = q(1);
01142       P(5) = q(2);
01143       V = (q(1)+q(2))/L;
01144       P(1) =  V+p0[1];
01145       P(4) = -V+p0[2];
01146       return eleInfo.setVector(P);
01147   }
01148 
01149   else if (responseID == 9) {
01150     return eleInfo.setVector(q);
01151   }
01152 
01153   // Chord rotation
01154   else if (responseID == 3)
01155     return eleInfo.setVector(crdTransf->getBasicTrialDisp());
01156 
01157   // Plastic rotation
01158   else if (responseID == 4) {
01159     static Vector vp(3);
01160     static Vector ve(3);
01161     const Matrix &kb = this->getInitialBasicStiff();
01162     kb.Solve(q, ve);
01163     vp = crdTransf->getBasicTrialDisp();
01164     vp -= ve;
01165     return eleInfo.setVector(vp);
01166   }
01167 
01168   // Curvature sensitivity
01169   else if (responseID == 5) {
01170     /*
01171       Vector curv(numSections);
01172       const Vector &v = crdTransf->getBasicDispGradient(1);
01173       
01174       double L = crdTransf->getInitialLength();
01175       double oneOverL = 1.0/L;
01176       //const Matrix &pts = quadRule.getIntegrPointCoords(numSections);
01177       double pts[2];
01178       pts[0] = 0.0;
01179       pts[1] = 1.0;
01180       
01181       // Loop over the integration points
01182       for (int i = 0; i < numSections; i++) {
01183         int order = theSections[i]->getOrder();
01184         const ID &code = theSections[i]->getType();
01185         //double xi6 = 6.0*pts(i,0);
01186         double xi6 = 6.0*pts[i];
01187         curv(i) = oneOverL*((xi6-4.0)*v(1) + (xi6-2.0)*v(2));
01188       }
01189       
01190       return eleInfo.setVector(curv);
01191     */
01192 
01193     Vector curv(numSections);
01194 
01195     /*
01196     // Loop over the integration points
01197     for (int i = 0; i < numSections; i++) {
01198       int order = theSections[i]->getOrder();
01199       const ID &code = theSections[i]->getType();
01200       const Vector &dedh = theSections[i]->getdedh();
01201       for (int j = 0; j < order; j++) {
01202         if (code(j) == SECTION_RESPONSE_MZ)
01203           curv(i) = dedh(j);
01204       }
01205     }
01206     */
01207 
01208     return eleInfo.setVector(curv);
01209   }
01210 
01211   // Basic deformation sensitivity
01212   else if (responseID == 6) {  
01213     const Vector &dvdh = crdTransf->getBasicDisplSensitivity(1);
01214     return eleInfo.setVector(dvdh);
01215   }
01216 
01217   else if (responseID == 7) {
01218     //const Matrix &pts = quadRule.getIntegrPointCoords(numSections);
01219     double xi[10];
01220     beamInt->getSectionLocations(numSections, L, xi);
01221     Vector locs(numSections);
01222     for (int i = 0; i < numSections; i++)
01223       locs(i) = xi[i]*L;
01224     return eleInfo.setVector(locs);
01225   }
01226 
01227   else if (responseID == 8) {
01228     //const Vector &wts = quadRule.getIntegrPointWeights(numSections);
01229     double wt[10];
01230     beamInt->getSectionWeights(numSections, L, wt);
01231     Vector weights(numSections);
01232     for (int i = 0; i < numSections; i++)
01233       weights(i) = wt[i]*L;
01234     return eleInfo.setVector(weights);
01235   }
01236 
01237   else
01238     return -1;
01239 }
01240 
01241 
01242 // AddingSensitivity:BEGIN ///////////////////////////////////
01243 int
01244 DispBeamColumn2d::setParameter(const char **argv, int argc, Parameter &param)
01245 {
01246   if (argc < 1)
01247     return -1;
01248   
01249   // If the parameter belongs to the element itself
01250   if (strcmp(argv[0],"rho") == 0)
01251     return param.addObject(1, this);
01252   
01253   // If the parameter is belonging to a section or lower
01254   if (strstr(argv[0],"section") != 0) {
01255     
01256     if (argc < 3)
01257       return -1;
01258     
01259     // Get section and material tag numbers from user input
01260     int paramSectionTag = atoi(argv[1]);
01261     
01262     // Find the right section and call its setParameter method
01263     int ok = 0;
01264     for (int i = 0; i < numSections; i++)
01265       if (paramSectionTag == theSections[i]->getTag())
01266         ok += theSections[i]->setParameter(&argv[2], argc-2, param);
01267 
01268     return ok;
01269   }
01270   
01271   else if (strstr(argv[0],"integration") != 0) {
01272     
01273     if (argc < 2)
01274       return -1;
01275 
01276     return beamInt->setParameter(&argv[1], argc-1, param);
01277   }
01278 
01279   else {
01280     opserr << "DispBeamColumn2d::setParameter() - could not set parameter. " << endln;
01281     return -1;
01282   }
01283 }
01284 
01285 int
01286 DispBeamColumn2d::updateParameter (int parameterID, Information &info)
01287 {
01288   if (parameterID == 1) {
01289     rho = info.theDouble;
01290     return 0;
01291   }
01292   else
01293     return -1;  
01294 }
01295 
01296 
01297 
01298 
01299 int
01300 DispBeamColumn2d::activateParameter(int passedParameterID)
01301 {
01302   parameterID = passedParameterID;
01303   
01304   return 0;
01305 }
01306 
01307 
01308 
01309 const Matrix &
01310 DispBeamColumn2d::getKiSensitivity(int gradNumber)
01311 {
01312         K.Zero();
01313         return K;
01314 }
01315 
01316 const Matrix &
01317 DispBeamColumn2d::getMassSensitivity(int gradNumber)
01318 {
01319         K.Zero();
01320         return K;
01321 }
01322 
01323 
01324 
01325 const Vector &
01326 DispBeamColumn2d::getResistingForceSensitivity(int gradNumber)
01327 {
01328   double L = crdTransf->getInitialLength();
01329   double oneOverL = 1.0/L;
01330   
01331   //const Matrix &pts = quadRule.getIntegrPointCoords(numSections);
01332   //const Vector &wts = quadRule.getIntegrPointWeights(numSections);
01333   double xi[10];
01334   beamInt->getSectionLocations(numSections, L, xi);
01335   double wt[10];
01336   beamInt->getSectionWeights(numSections, L, wt);
01337 
01338   // Zero for integration
01339   static Vector dqdh(3);
01340   dqdh.Zero();
01341   
01342   // Loop over the integration points
01343   for (int i = 0; i < numSections; i++) {
01344     
01345     int order = theSections[i]->getOrder();
01346     const ID &code = theSections[i]->getType();
01347     
01348     //double xi6 = 6.0*pts(i,0);
01349     double xi6 = 6.0*xi[i];
01350     //double wti = wts(i);
01351     double wti = wt[i];
01352     
01353     // Get section stress resultant gradient
01354     const Vector &dsdh = theSections[i]->getStressResultantSensitivity(gradNumber,true);
01355     
01356     // Perform numerical integration on internal force gradient
01357     double sensi;
01358     for (int j = 0; j < order; j++) {
01359       sensi = dsdh(j)*wti;
01360       switch(code(j)) {
01361       case SECTION_RESPONSE_P:
01362         dqdh(0) += sensi; 
01363         break;
01364       case SECTION_RESPONSE_MZ:
01365         dqdh(1) += (xi6-4.0)*sensi; 
01366         dqdh(2) += (xi6-2.0)*sensi; 
01367         break;
01368       default:
01369         break;
01370       }
01371     }
01372   }
01373   
01374   // Transform forces
01375   static Vector dp0dh(3);               // No distributed loads
01376 
01377   P.Zero();
01378 
01380 
01381   if (crdTransf->isShapeSensitivity()) {
01382     
01383     // Perform numerical integration to obtain basic stiffness matrix
01384     // Some extra declarations
01385     static Matrix kbmine(3,3);
01386     kbmine.Zero();
01387     q.Zero();
01388     
01389     double tmp;
01390     
01391     int j, k;
01392     
01393     for (int i = 0; i < numSections; i++) {
01394       
01395       int order = theSections[i]->getOrder();
01396       const ID &code = theSections[i]->getType();
01397       
01398       //double xi6 = 6.0*pts(i,0);
01399       double xi6 = 6.0*xi[i];
01400       //double wti = wts(i);
01401       double wti = wt[i];
01402       
01403       const Vector &s = theSections[i]->getStressResultant();
01404       const Matrix &ks = theSections[i]->getSectionTangent();
01405       
01406       Matrix ka(workArea, order, 3);
01407       ka.Zero();
01408       
01409       double si;
01410       for (j = 0; j < order; j++) {
01411         si = s(j)*wti;
01412         switch(code(j)) {
01413         case SECTION_RESPONSE_P:
01414           q(0) += si;
01415           for (k = 0; k < order; k++) {
01416             ka(k,0) += ks(k,j)*wti;
01417           }
01418           break;
01419         case SECTION_RESPONSE_MZ:
01420           q(1) += (xi6-4.0)*si; 
01421           q(2) += (xi6-2.0)*si;
01422           for (k = 0; k < order; k++) {
01423             tmp = ks(k,j)*wti;
01424             ka(k,1) += (xi6-4.0)*tmp;
01425             ka(k,2) += (xi6-2.0)*tmp;
01426           }
01427           break;
01428         default:
01429           break;
01430         }
01431       }
01432       for (j = 0; j < order; j++) {
01433         switch (code(j)) {
01434         case SECTION_RESPONSE_P:
01435           for (k = 0; k < 3; k++) {
01436             kbmine(0,k) += ka(j,k);
01437           }
01438           break;
01439         case SECTION_RESPONSE_MZ:
01440           for (k = 0; k < 3; k++) {
01441             tmp = ka(j,k);
01442             kbmine(1,k) += (xi6-4.0)*tmp;
01443             kbmine(2,k) += (xi6-2.0)*tmp;
01444           }
01445           break;
01446         default:
01447           break;
01448         }
01449       }
01450     }      
01451     
01452     const Vector &A_u = crdTransf->getBasicTrialDisp();
01453     double dLdh = crdTransf->getdLdh();
01454     double d1overLdh = -dLdh/(L*L);
01455     // a^T k_s dadh v
01456     dqdh.addMatrixVector(1.0, kbmine, A_u, d1overLdh);
01457 
01458     // k dAdh u
01459     const Vector &dAdh_u = crdTransf->getBasicTrialDispShapeSensitivity();
01460     dqdh.addMatrixVector(1.0, kbmine, dAdh_u, oneOverL);
01461 
01462     // dAdh^T q
01463     P += crdTransf->getGlobalResistingForceShapeSensitivity(q, dp0dh, gradNumber);
01464   }
01465   
01466   // A^T (dqdh + k dAdh u)
01467   P += crdTransf->getGlobalResistingForce(dqdh, dp0dh);
01468   
01469   return P;
01470 }
01471 
01472 
01473 
01474 // NEW METHOD
01475 int
01476 DispBeamColumn2d::commitSensitivity(int gradNumber, int numGrads)
01477 {
01478   // Get basic deformation and sensitivities
01479   const Vector &v = crdTransf->getBasicTrialDisp();
01480   
01481   static Vector dvdh(3);
01482   dvdh = crdTransf->getBasicDisplSensitivity(gradNumber);
01483   
01484   double L = crdTransf->getInitialLength();
01485   double oneOverL = 1.0/L;
01486   //const Matrix &pts = quadRule.getIntegrPointCoords(numSections);
01487   double xi[10];
01488   beamInt->getSectionLocations(numSections, L, xi);
01489 
01490   // Some extra declarations
01491   double d1oLdh = crdTransf->getd1overLdh();
01492   
01493   // Loop over the integration points
01494   for (int i = 0; i < numSections; i++) {
01495     
01496     int order = theSections[i]->getOrder();
01497     const ID &code = theSections[i]->getType();
01498     
01499     Vector e(workArea, order);
01500     
01501     //double xi6 = 6.0*pts(i,0);
01502     double xi6 = 6.0*xi[i];
01503     
01504     for (int j = 0; j < order; j++) {
01505       switch(code(j)) {
01506       case SECTION_RESPONSE_P:
01507         e(j) = oneOverL*dvdh(0)
01508           + d1oLdh*v(0); 
01509         break;
01510       case SECTION_RESPONSE_MZ:
01511         e(j) = oneOverL*((xi6-4.0)*dvdh(1) + (xi6-2.0)*dvdh(2))
01512           + d1oLdh*((xi6-4.0)*v(1) + (xi6-2.0)*v(2)); 
01513         break;
01514       default:
01515         e(j) = 0.0; 
01516         break;
01517       }
01518     }
01519     
01520     // Set the section deformations
01521     theSections[i]->commitSensitivity(e,gradNumber,numGrads);
01522   }
01523   
01524   return 0;
01525 }
01526 
01527 
01528 // AddingSensitivity:END /////////////////////////////////////////////
01529 

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