BeamWithHinges3d.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.19 $
00022 // $Date: 2004/06/07 23:20:55 $
00023 // $Source: /usr/local/cvs/OpenSees/SRC/element/beamWithHinges/BeamWithHinges3d.cpp,v $
00024 
00025 #include <BeamWithHinges3d.h>
00026 #include <Element.h>
00027 #include <Domain.h>
00028 #include <Channel.h>
00029 #include <FEM_ObjectBroker.h>
00030 #include <Matrix.h>
00031 #include <Vector.h>                                             
00032 #include <Node.h>
00033 #include <MatrixUtil.h>
00034 #include <math.h>
00035 #include <stdlib.h>
00036 #include <string.h>
00037 #include <stdio.h>
00038 
00039 #include <SectionForceDeformation.h>
00040 #include <CrdTransf3d.h>
00041 
00042 #include <Information.h>
00043 #include <ElementResponse.h>
00044 #include <ElementalLoad.h>
00045 #include <Renderer.h>
00046 
00047 Matrix BeamWithHinges3d::theMatrix(12,12);
00048 Vector BeamWithHinges3d::theVector(12);
00049 double BeamWithHinges3d::workArea[200];
00050 
00051 BeamWithHinges3d::BeamWithHinges3d(void)
00052   :Element(0, ELE_TAG_BeamWithHinges3d),
00053    E(0.0), A(0.0), Iz(0.0), Iy(0.0), G(0.0), J(0.0),
00054    beta1(0.0), beta2(0.0), rho(0.0),
00055    theCoordTransf(0),
00056    connectedExternalNodes(2),
00057    kb(6,6), q(6), load(12),
00058    kbCommit(6,6), qCommit(6),
00059    initialFlag(0), maxIter(0), tolerance(0.0), sp(0)
00060 {
00061   section[0] = 0;
00062   section[1] = 0;
00063 
00064   p0[0] = 0.0;
00065   p0[1] = 0.0;
00066   p0[2] = 0.0;
00067   p0[3] = 0.0;
00068   p0[4] = 0.0;
00069 
00070   v0[0] = 0.0;
00071   v0[1] = 0.0;
00072   v0[2] = 0.0;
00073   v0[3] = 0.0;
00074   v0[4] = 0.0;
00075 
00076   theNodes[0] = 0;
00077   theNodes[1] = 0;
00078 }
00079 
00080 BeamWithHinges3d::BeamWithHinges3d(int tag, int nodeI, int nodeJ,
00081                                    double e, double a, double iz,
00082                                    double iy, double g, double j,
00083                                    SectionForceDeformation &sectionRefI, double lpi,
00084                                    SectionForceDeformation &sectionRefJ, double lpj,
00085                                    CrdTransf3d &coordTransf,
00086                                    double r, int max, double tol)
00087   :Element(tag, ELE_TAG_BeamWithHinges3d),
00088    E(e), A(a), Iz(iz), Iy(iy), G(g), J(j),
00089    beta1(lpi), beta2(lpj), rho(r),
00090    theCoordTransf(0),
00091    connectedExternalNodes(2),
00092    kb(6,6), q(6), load(12),
00093    kbCommit(6,6), qCommit(6),
00094    initialFlag(0), maxIter(max), tolerance(tol), sp(0)
00095 {
00096   if (E <= 0.0)  {
00097     opserr << "BeamWithHinges3d::BeamWithHinges3d -- input parameter E is <= 0.0\n";
00098     exit(-1);
00099   }
00100 
00101   if (A <= 0.0)  {
00102     opserr << "BeamWithHinges3d::BeamWithHinges3d -- input parameter A is <= 0.0\n";
00103     exit(-1);
00104   }
00105   
00106   if (Iz <= 0.0)  {
00107     opserr << "BeamWithHinges3d::BeamWithHinges3d -- input parameter Iz is <= 0.0\n";
00108     exit(-1);
00109   }
00110 
00111   if (Iy <= 0.0)  {
00112     opserr << "BeamWithHinges3d::BeamWithHinges3d -- input parameter Iy is <= 0.0\n";
00113     exit(-1);
00114   }
00115   
00116   if (G <= 0.0)  {
00117     opserr << "BeamWithHinges3d::BeamWithHinges3d -- input parameter G is <= 0.0\n";
00118     exit(-1);
00119   }
00120 
00121   if (J <= 0.0)  {
00122     opserr << "BeamWithHinges3d::BeamWithHinges3d -- input parameter J is <= 0.0\n";
00123     exit(-1);
00124   }
00125   
00126   // Get copies of sections
00127   section[0] = sectionRefI.getCopy();
00128   
00129   if (section[0] == 0) {
00130     opserr << "BeamWithHinges3d::BeamWithHinges3d -- failed to get copy of section I\n";
00131     exit(-1);
00132   }
00133   
00134   section[1] = sectionRefJ.getCopy();
00135   
00136   if (section[1] == 0) {
00137     opserr << "BeamWithHinges3d::BeamWithHinges3d -- failed to get copy of section J\n";
00138     exit(-1);
00139   }
00140   
00141   theCoordTransf = coordTransf.getCopy();
00142   
00143   if (theCoordTransf == 0) {
00144     opserr << "BeamWithHinges3d::BeamWithHinges3d -- failed to get copy of coordinate transformation\n";
00145     exit(-1);
00146   }
00147   
00148   connectedExternalNodes(0) = nodeI;
00149   connectedExternalNodes(1) = nodeJ;
00150 
00151   theNodes[0] = 0;
00152   theNodes[1] = 0;
00153 
00154   p0[0] = 0.0;
00155   p0[1] = 0.0;
00156   p0[2] = 0.0;
00157   p0[3] = 0.0;
00158   p0[4] = 0.0;
00159 
00160   v0[0] = 0.0;
00161   v0[1] = 0.0;
00162   v0[2] = 0.0;
00163   v0[3] = 0.0;
00164   v0[4] = 0.0;
00165 }
00166 
00167 BeamWithHinges3d::~BeamWithHinges3d(void)
00168 {
00169   for (int i = 0; i < 2; i++)
00170     if (section[i] != 0)
00171       delete section[i];
00172   
00173   if (theCoordTransf)
00174     delete theCoordTransf;
00175 
00176   if (sp != 0)
00177     delete sp;
00178 }
00179 
00180 int 
00181 BeamWithHinges3d::getNumExternalNodes(void) const
00182 {
00183   return 2;
00184 }
00185 
00186 const ID &
00187 BeamWithHinges3d::getExternalNodes(void)
00188 {
00189   return connectedExternalNodes;
00190 }
00191 
00192 Node **
00193 BeamWithHinges3d::getNodePtrs()
00194 {
00195     return theNodes;
00196 }
00197 
00198 
00199 int 
00200 BeamWithHinges3d::getNumDOF(void)
00201 {
00202   return 12;
00203 }
00204 
00205 void
00206 BeamWithHinges3d::setDomain(Domain *theDomain)
00207 {
00208   //This function may be called after a beam is constructed, so
00209   //geometry may change.  Therefore calculate all beam geometry here.
00210   
00211   if(theDomain == 0) {
00212     theNodes[0] = 0;
00213     theNodes[1] = 0;
00214     return;
00215   }
00216   
00217   // set the node pointers and verify them
00218   this->setNodePtrs(theDomain);
00219   
00220   // call the DomainComponent version of the function
00221   this->DomainComponent::setDomain(theDomain);
00222   
00223   if (theCoordTransf->initialize(theNodes[0], theNodes[1]) != 0) {
00224     opserr << "BeamWithHinges3d::setDomain() -- failed to initialize coordinate transformation\n";
00225     exit(-1);
00226   }
00227   
00228   // get element length
00229   double L = theCoordTransf->getInitialLength();
00230   if (L == 0.0) {
00231     opserr << "BeamWithHinges3d::setDomain() -- element has zero length\n";
00232     exit(-1);
00233   }
00234 
00235   // Set up section interpolation and hinge lengths
00236   this->setHinges();
00237 
00238   if (initialFlag == 2)
00239     theCoordTransf->update();
00240   else
00241     this->update();
00242 }
00243 
00244 int
00245 BeamWithHinges3d::commitState(void)
00246 {
00247   int err = 0;
00248 
00249   // call element commitState to do any base class stuff
00250   if ((err = this->Element::commitState()) != 0) {
00251     opserr << "BeamWithHinges3d::commitState () - failed in base class\n";
00252   }    
00253   
00254   for (int i = 0; i < 2; i++) {
00255     if (section[i] != 0)
00256       err += section[i]->commitState();
00257   }
00258   
00259   err += theCoordTransf->commitState();
00260   
00261   kbCommit = kb;
00262   qCommit = q;
00263 
00264   eCommit[0] = e[0];
00265   eCommit[1] = e[1];
00266   
00267   //initialFlag = 0;
00268   
00269   return err;
00270 }
00271 
00272 int
00273 BeamWithHinges3d::revertToLastCommit(void)
00274 {
00275   int err = 0;
00276   
00277   // Revert the sections and then get their last commited
00278   // deformations, stress resultants, and flexibilities
00279   for (int i = 0; i < 2; i++) {
00280     if (section[i] != 0) {
00281       err += section[i]->revertToLastCommit();
00282       section[i]->setTrialSectionDeformation(eCommit[i]);
00283 
00284       e[i] = eCommit[i];
00285       sr[i] = section[i]->getStressResultant();
00286       fs[i] = section[i]->getSectionFlexibility();
00287     }
00288   }
00289   
00290   // Commit the coordinate transformation
00291   err += theCoordTransf->revertToLastCommit();
00292   
00293   kb = kbCommit;
00294   q = qCommit;
00295   
00296   initialFlag = 0;
00297 
00298   return err;
00299 }
00300 
00301 int
00302 BeamWithHinges3d::revertToStart(void)
00303 {
00304   int err = 0;
00305   
00306   for (int i = 0; i < 2; i++) {
00307     if (section[i] != 0) {
00308       err += section[i]->revertToStart();
00309       fs[i].Zero();
00310       e[i].Zero();
00311       sr[i].Zero();
00312       eCommit[i].Zero();
00313     }
00314   }
00315   
00316   err += theCoordTransf->revertToStart();
00317   
00318   kb.Zero();
00319   q.Zero();
00320   
00321   initialFlag = 0;
00322   this->update();
00323 
00324   return err;
00325 }
00326 
00327 const Matrix &
00328 BeamWithHinges3d::getTangentStiff(void)
00329 {
00330   return theCoordTransf->getGlobalStiffMatrix(kb, q);
00331 }
00332 
00333 
00334 const Matrix &
00335 BeamWithHinges3d::getInitialStiff(void)
00336 {
00337   double L = theCoordTransf->getInitialLength();
00338   double oneOverL = 1.0/L;
00339 
00340   // Section locations along element length ...
00341   double xi[2];
00342 
00343   // and their integration weights
00344   double lp[2];
00345   
00346   lp[0] = beta1*L;
00347   lp[1] = beta2*L;
00348 
00349   xi[0] = 0.5*lp[0];
00350   xi[1] = L-0.5*lp[1];
00351   
00352   // element properties
00353   static Matrix f(6,6); // element flexibility
00354   static Matrix Iden(6,6);   // an identity matrix for matrix inverse
00355   Iden.Zero();
00356   int i;
00357   for (i = 0; i < 6; i++)
00358     Iden(i,i) = 1.0;
00359 
00360   // Length of elastic interior
00361   double Le = L-lp[0]-lp[1];
00362   double LoverEA   = Le/(E*A);
00363   double Lover3EIz = Le/(3*E*Iz);
00364   double Lover6EIz = 0.5*Lover3EIz;
00365   double Lover3EIy = Le/(3*E*Iy);
00366   double Lover6EIy = 0.5*Lover3EIy;
00367   double LoverGJ   = Le/(G*J);
00368 
00369   // Elastic flexibility of element interior
00370   static Matrix fe(4,4);
00371   fe(0,0) = fe(1,1) =  Lover3EIz;
00372   fe(0,1) = fe(1,0) = -Lover6EIz;
00373   fe(2,2) = fe(3,3) =  Lover3EIy;
00374   fe(2,3) = fe(3,2) = -Lover6EIy;
00375   
00376   // Equilibrium transformation matrix
00377   static Matrix B(4,4);
00378   B(0,0) = B(2,2) = 1.0 - beta1;
00379   B(1,1) = B(3,3) = 1.0 - beta2;
00380   B(0,1) = B(2,3) = -beta1;
00381   B(1,0) = B(3,2) = -beta2;
00382   
00383   // Transform the elastic flexibility of the element
00384   // interior to the basic system
00385   static Matrix fElastic(4,4);
00386   fElastic.addMatrixTripleProduct(0.0, B, fe, 1.0);
00387     
00388   // Set element flexibility to flexibility of elastic region
00389   f.Zero();
00390   f(0,0) = LoverEA;
00391   f(1,1) = fElastic(0,0);
00392   f(2,2) = fElastic(1,1);
00393   f(1,2) = fElastic(0,1);
00394   f(2,1) = fElastic(1,0);
00395   f(3,3) = fElastic(2,2);
00396   f(4,4) = fElastic(3,3);
00397   f(3,4) = fElastic(2,3);
00398   f(4,3) = fElastic(3,2);
00399   f(5,5) = LoverGJ;    
00400   
00401   for (i = 0; i < 2; i++) {
00402     
00403     if (section[i] == 0 || lp[i] <= 0.0)
00404       continue;
00405     
00406     // Get section information
00407     int order = section[i]->getOrder();
00408     const ID &code = section[i]->getType();
00409     
00410     Vector s(workArea, order);
00411     Vector ds(&workArea[order], order);
00412     Vector de(&workArea[2*order], order);
00413     
00414     Matrix fb(&workArea[3*order], order, 6);
00415     
00416     double xL = xi[i]*oneOverL;
00417     double xL1 = xL-1.0;
00418     
00419     // get section flexibility matrix
00420     const Matrix &fSec = section[i]->getInitialFlexibility();
00421       
00422     // integrate section flexibility matrix
00423     // f += (b^ fs * b) * lp[i];
00424     //f.addMatrixTripleProduct(1.0, b, fSec, lp[i]);
00425     int ii, jj;
00426     fb.Zero();
00427     double tmp;
00428     for (ii = 0; ii < order; ii++) {
00429       switch(code(ii)) {
00430       case SECTION_RESPONSE_P:
00431         for (jj = 0; jj < order; jj++)
00432           fb(jj,0) += fSec(jj,ii)*lp[i];
00433         break;
00434       case SECTION_RESPONSE_MZ:
00435         for (jj = 0; jj < order; jj++) {
00436           tmp = fSec(jj,ii)*lp[i];
00437           fb(jj,1) += xL1*tmp;
00438           fb(jj,2) += xL*tmp;
00439         }
00440         break;
00441       case SECTION_RESPONSE_VY:
00442         for (jj = 0; jj < order; jj++) {
00443           //tmp = oneOverL*fSec(jj,ii)*lp[i]*L/lp[i];
00444           tmp = fSec(jj,ii);
00445           fb(jj,1) += tmp;
00446           fb(jj,2) += tmp;
00447         }
00448         break;
00449       case SECTION_RESPONSE_MY:
00450         for (jj = 0; jj < order; jj++) {
00451           tmp = fSec(jj,ii)*lp[i];
00452           fb(jj,3) += xL1*tmp;
00453           fb(jj,4) += xL*tmp;
00454           }
00455         break;
00456       case SECTION_RESPONSE_VZ:
00457         for (jj = 0; jj < order; jj++) {
00458           //tmp = oneOverL*fSec(jj,ii)*lp[i]*L/lp[i];
00459           tmp = fSec(jj,ii);
00460           fb(jj,3) += tmp;
00461           fb(jj,4) += tmp;
00462         }
00463         break;
00464       case SECTION_RESPONSE_T:
00465         for (jj = 0; jj < order; jj++)
00466           fb(jj,5) += fSec(jj,ii)*lp[i];
00467         break;
00468       default:
00469         break;
00470       }
00471     }
00472     for (ii = 0; ii < order; ii++) {
00473       switch (code(ii)) {
00474       case SECTION_RESPONSE_P:
00475         for (jj = 0; jj < 6; jj++)
00476           f(0,jj) += fb(ii,jj);
00477         break;
00478       case SECTION_RESPONSE_MZ:
00479         for (jj = 0; jj < 6; jj++) {
00480           tmp = fb(ii,jj);
00481           f(1,jj) += xL1*tmp;
00482           f(2,jj) += xL*tmp;
00483         }
00484         break;
00485       case SECTION_RESPONSE_VY:
00486         for (jj = 0; jj < 6; jj++) {
00487           tmp = oneOverL*fb(ii,jj);
00488           f(1,jj) += tmp;
00489           f(2,jj) += tmp;
00490         }
00491         break;
00492       case SECTION_RESPONSE_MY:
00493         for (jj = 0; jj < 6; jj++) {
00494           tmp = fb(ii,jj);
00495           f(3,jj) += xL1*tmp;
00496           f(4,jj) += xL*tmp;
00497         }
00498         break;
00499       case SECTION_RESPONSE_VZ:
00500         for (jj = 0; jj < 6; jj++) {
00501           tmp = oneOverL*fb(ii,jj);
00502           f(3,jj) += tmp;
00503           f(4,jj) += tmp;
00504         }
00505         break;
00506       case SECTION_RESPONSE_T:
00507         for (jj = 0; jj < 6; jj++)
00508           f(5,jj) += fb(ii,jj);
00509         break;
00510       default:
00511         break;
00512       }
00513     }
00514     
00515   }
00516   // calculate element stiffness matrix
00517   static Matrix kbInit(6,6);
00518   if (f.Solve(Iden,kbInit) < 0)
00519     opserr << "BeamWithHinges3d::update() -- could not invert flexibility\n";
00520   
00521   return theCoordTransf->getInitialGlobalStiffMatrix(kbInit);
00522 }
00523 
00524 const Matrix &
00525 BeamWithHinges3d::getMass(void)
00526 {
00527   theMatrix.Zero();
00528 
00529   if (rho != 0.0) {
00530     double L = theCoordTransf->getInitialLength();  
00531     theMatrix(0,0) = theMatrix(1,1) = theMatrix(2,2) = 
00532       theMatrix(6,6) = theMatrix(7,7) = theMatrix(8,8) = 0.5*L*rho;
00533   }
00534   
00535   return theMatrix;
00536 }
00537 
00538 void 
00539 BeamWithHinges3d::zeroLoad(void)
00540 {
00541   if (sp != 0)
00542     sp->Zero();
00543 
00544   p0[0] = 0.0;
00545   p0[1] = 0.0;
00546   p0[2] = 0.0;
00547   p0[3] = 0.0;
00548   p0[4] = 0.0;
00549 
00550   v0[0] = 0.0;
00551   v0[1] = 0.0;
00552   v0[2] = 0.0;
00553   v0[3] = 0.0;
00554   v0[4] = 0.0;
00555 
00556   load.Zero();
00557 }
00558 
00559 int
00560 BeamWithHinges3d::addLoad(ElementalLoad *theLoad, double loadFactor)
00561 {
00562   int type;
00563   const Vector &data = theLoad->getData(type, loadFactor);
00564   
00565   if (sp == 0) {
00566     sp = new Matrix(5,2);
00567     if (sp == 0)
00568       opserr << "BeamWithHinges3d::addLoad() -- out of memory\n";
00569   }
00570 
00571   double L = theCoordTransf->getInitialLength();
00572   double oneOverL = 1.0/L;
00573 
00574   double lp1 = beta1*L;
00575   double lp2 = beta2*L;
00576   double Le = L-lp1-lp2;
00577 
00578   // Section locations along element length ...
00579   double xi[2];
00580   xi[0] = 0.5*lp1;
00581   xi[1] = L-0.5*lp2;
00582 
00583   if (type == LOAD_TAG_Beam3dUniformLoad) {
00584     double wy = data(0)*loadFactor;  // Transverse
00585     double wz = data(1)*loadFactor;  // Transverse
00586     double wx = data(2)*loadFactor;  // Axial
00587 
00588     Matrix &s_p = *sp;
00589 
00590     // Accumulate applied section forces due to uniform load
00591     for (int i = 0; i < 2; i++) {
00592       double x = xi[i];
00593       // Axial
00594       s_p(0,i) += wx*(L-x);
00595       // Moment
00596       s_p(1,i) += wy*0.5*x*(x-L);
00597       // Shear
00598       s_p(2,i) += wy*(x-0.5*L);
00599       // Moment
00600       s_p(3,i) += wz*0.5*x*(x-L);
00601       // Shear
00602       s_p(4,i) += wz*(x-0.5*L);
00603     }
00604 
00605     // Accumulate reactions in basic system
00606     p0[0] -= wx*L;
00607     double V;
00608     V = 0.5*wy*L;
00609     p0[1] -= V;
00610     p0[2] -= V;
00611     V = 0.5*wz*L;
00612     p0[3] -= V;
00613     p0[4] -= V;
00614 
00615     // Quick return
00616     if (Le == 0.0)
00617       return 0;
00618 
00619     // Accumulate basic deformations due to uniform load on interior
00620     // Midpoint rule for axial
00621     v0[0] += wx*0.5*(L-lp1+lp2)/(E*A)*Le;
00622 
00623     // Two point Gauss for bending ... will not be exact when
00624     // hinge lengths are not equal, but this is not a big deal!!!
00625     double x1 = lp1 + 0.5*Le*(1.0-1.0/sqrt(3.0));
00626     double x2 = lp1 + 0.5*Le*(1.0+1.0/sqrt(3.0));
00627 
00628     double Mz1 = 0.5*wy*x1*(x1-L);
00629     double Mz2 = 0.5*wy*x2*(x2-L);
00630 
00631     double My1 = 0.5*wz*x1*(x1-L);
00632     double My2 = 0.5*wz*x2*(x2-L);
00633 
00634     double Le2EIz = Le/(2*E*Iz);
00635     double Le2EIy = Le/(2*E*Iy);
00636 
00637     double b1, b2;
00638     b1 = x1*oneOverL;
00639     b2 = x2*oneOverL;
00640     v0[2] += Le2EIz*(b1*Mz1+b2*Mz2);
00641     v0[4] += Le2EIy*(b1*My1+b2*My2);
00642 
00643     b1 -= 1.0;
00644     b2 -= 1.0;
00645     v0[1] += Le2EIz*(b1*Mz1+b2*Mz2);
00646     v0[3] += Le2EIy*(b1*My1+b2*My2);
00647   }
00648 
00649   else if (type == LOAD_TAG_Beam3dPointLoad) {
00650     double Py = data(0)*loadFactor;
00651     double Pz = data(1)*loadFactor;
00652     double N  = data(2)*loadFactor;
00653     double aOverL = data(3);
00654     double a = aOverL*L;
00655 
00656     double Vy2 = Py*aOverL;
00657     double Vy1 = Py-Vy2;
00658 
00659     double Vz2 = Pz*aOverL;
00660     double Vz1 = Pz-Vz2;
00661 
00662     Matrix &s_p = *sp;
00663 
00664     // Accumulate applied section forces due to point load
00665     for (int i = 0; i < 2; i++) {
00666       double x = xi[i];
00667       if (x <= a) {
00668         s_p(0,i) += N;
00669         s_p(1,i) -= x*Vy1;
00670         s_p(2,i) -= Vy1;
00671         s_p(3,i) -= x*Vz1;
00672         s_p(4,i) -= Vz1;
00673       }
00674       else {
00675         s_p(1,i) -= (L-x)*Vy2;
00676         s_p(2,i) += Vy2;
00677         s_p(3,i) -= (L-x)*Vz2;
00678         s_p(4,i) += Vz2;
00679       }
00680     }
00681 
00682     // Accumulate reactions in basic system
00683     p0[0] -= N;
00684     p0[1] -= Vy1;
00685     p0[2] -= Vy2;
00686     p0[3] -= Vz1;
00687     p0[4] -= Vz2;
00688 
00689     // Quick return
00690     if (Le == 0.0)
00691       return 0;
00692 
00693     // Accumulate basic deformations of interior due to point load
00694     double M1, M2, M3;
00695     double b1, b2, b3;
00696 
00697     // Point load is on left hinge
00698     if (a < lp1) {
00699       M1 = (lp1-L)*Vy2;
00700       M2 = -lp2*Vy2;
00701 
00702       double Le_6EI;
00703       Le_6EI = Le/(6*E*Iz);
00704 
00705       b1 = lp1*oneOverL;
00706       b2 = 1.0-lp2*oneOverL;
00707       v0[2] += Le_6EI*(M1*(2*b1+b2)+M2*(b1+2*b2));
00708 
00709       b1 -= 1.0;
00710       b2 -= 1.0;
00711       v0[1] += Le_6EI*(M1*(2*b1+b2)+M2*(b1+2*b2));
00712 
00713       M1 = (lp1-L)*Vz2;
00714       M2 = -lp2*Vz2;
00715 
00716       Le_6EI = Le/(6*E*Iy);
00717 
00718       b1 = lp1*oneOverL;
00719       b2 = 1.0-lp2*oneOverL;
00720       v0[4] += Le_6EI*(M1*(2*b1+b2)+M2*(b1+2*b2));
00721 
00722       b1 -= 1.0;
00723       b2 -= 1.0;
00724       v0[3] += Le_6EI*(M1*(2*b1+b2)+M2*(b1+2*b2));
00725 
00726       // Nothing to do for axial
00727       //v0[0] += 0.0;
00728     }
00729     // Point load is on right hinge
00730     else if (a > L-lp2) {
00731       M1 = -lp1*Vy1;
00732       M2 = (lp2-L)*Vy1;
00733 
00734       double Le_6EI;
00735       Le_6EI = Le/(6*E*Iz);
00736 
00737       b1 = lp1*oneOverL;
00738       b2 = 1.0-lp2*oneOverL;
00739       v0[2] += Le_6EI*(M1*(2*b1+b2)+M2*(b1+2*b2));
00740 
00741       b1 -= 1.0;
00742       b2 -= 1.0;
00743       v0[1] += Le_6EI*(M1*(2*b1+b2)+M2*(b1+2*b2));
00744 
00745       M1 = -lp1*Vz1;
00746       M2 = (lp2-L)*Vz1;
00747 
00748       Le_6EI = Le/(6*E*Iy);
00749 
00750       b1 = lp1*oneOverL;
00751       b2 = 1.0-lp2*oneOverL;
00752       v0[4] += Le_6EI*(M1*(2*b1+b2)+M2*(b1+2*b2));
00753 
00754       b1 -= 1.0;
00755       b2 -= 1.0;
00756       v0[3] += Le_6EI*(M1*(2*b1+b2)+M2*(b1+2*b2));
00757 
00758       v0[0] += N*Le/(E*A);      
00759     }
00760     // Point load is on elastic interior
00761     else {
00762       M1 = -lp1*Vy1;
00763       M2 = -lp2*Vy2;
00764       M3 = -a*Vy1;
00765 
00766       double L1_6EI;
00767       double L2_6EI;
00768 
00769       L1_6EI = (a-lp1)/(6*E*Iz);
00770       L2_6EI = (Le-a+lp1)/(6*E*Iz);
00771 
00772       b1 = lp1*oneOverL;
00773       b2 = 1.0-lp2*oneOverL;
00774       b3 = a*oneOverL;
00775       v0[2] += L1_6EI*(M1*(2*b1+b3)+M3*(b1+2*b3));
00776       v0[2] += L2_6EI*(M2*(2*b2+b3)+M3*(b2+2*b3));
00777 
00778       b1 -= 1.0;
00779       b2 -= 1.0;
00780       b3 -= 1.0;
00781       v0[1] += L1_6EI*(M1*(2*b1+b3)+M3*(b1+2*b3));
00782       v0[1] += L2_6EI*(M2*(2*b2+b3)+M3*(b2+2*b3));
00783 
00784       M1 = -lp1*Vz1;
00785       M2 = -lp2*Vz2;
00786       M3 = -a*Vz1;
00787 
00788       L1_6EI = (a-lp1)/(6*E*Iy);
00789       L2_6EI = (Le-a+lp1)/(6*E*Iy);
00790 
00791       b1 = lp1*oneOverL;
00792       b2 = 1.0-lp2*oneOverL;
00793       b3 = a*oneOverL;
00794       v0[4] += L1_6EI*(M1*(2*b1+b3)+M3*(b1+2*b3));
00795       v0[4] += L2_6EI*(M2*(2*b2+b3)+M3*(b2+2*b3));
00796 
00797       b1 -= 1.0;
00798       b2 -= 1.0;
00799       b3 -= 1.0;
00800       v0[3] += L1_6EI*(M1*(2*b1+b3)+M3*(b1+2*b3));
00801       v0[3] += L2_6EI*(M2*(2*b2+b3)+M3*(b2+2*b3));
00802 
00803       v0[0] += N*(a-lp1)/(E*A);
00804     }
00805   }
00806 
00807   else {
00808     opserr << "BeamWithHinges3d::addLoad() -- load type unknown for element with tag: " << this->getTag() << endln;
00809     return -1;
00810   }
00811 
00812   return 0;  
00813 }
00814 
00815 int
00816 BeamWithHinges3d::addInertiaLoadToUnbalance(const Vector &accel)
00817 {
00818   if (rho == 0.0)
00819     return 0;
00820   
00821   const Vector &Raccel1 = theNodes[0]->getRV(accel);
00822   const Vector &Raccel2 = theNodes[1]->getRV(accel);
00823   
00824   double L = theCoordTransf->getInitialLength();
00825   double mass = 0.5*L*rho;
00826   
00827   int i,j;
00828   for (i = 0, j = 6; i < 3; i++, j++) {
00829     load(i) += mass*Raccel1(i);
00830     load(j) += mass*Raccel2(i); // Yes, this should be 'i'
00831   }
00832   
00833   return 0;
00834 }
00835 
00836 const Vector &
00837 BeamWithHinges3d::getResistingForce(void)
00838 {
00839   Vector p0Vec(p0, 5);
00840 
00841   return theCoordTransf->getGlobalResistingForce(q, p0Vec);
00842 }
00843 
00844 const Vector &
00845 BeamWithHinges3d::getResistingForceIncInertia(void)
00846 {
00847   theVector = this->getResistingForce();
00848 
00849   if (rho != 0.0) {
00850   
00851     double ag[12];
00852     
00853     const Vector &accel1 = theNodes[0]->getTrialAccel();
00854     const Vector &accel2 = theNodes[1]->getTrialAccel();
00855     
00856     ag[0] = accel1(0);
00857     ag[1] = accel1(1);
00858     ag[2] = accel1(2);
00859     ag[6] = accel2(0);
00860     ag[7] = accel2(1);
00861     ag[8] = accel2(2);
00862     
00863     theVector = this->getResistingForce();
00864     
00865     double L = theCoordTransf->getInitialLength();
00866     double mass = 0.5*L*rho;
00867     
00868     int i,j;
00869     for (i = 0, j = 6; i < 3; i++, j++) {
00870       theVector(i) += mass*ag[i];
00871       theVector(j) += mass*ag[j];
00872     }
00873   
00874     // add the damping forces if rayleigh damping
00875     if (alphaM != 0.0 || betaK != 0.0 || betaK0 != 0.0 || betaKc != 0.0)
00876       theVector += this->getRayleighDampingForces();
00877   
00878   } else {
00879 
00880     // add the damping forces if rayleigh damping
00881     if (betaK != 0.0 || betaK0 != 0.0 || betaKc != 0.0)
00882       theVector += this->getRayleighDampingForces();
00883 
00884   }
00885   return theVector;
00886 }
00887 
00888 int
00889 BeamWithHinges3d::sendSelf(int commitTag, Channel &theChannel)
00890 {
00891   // place the integer data into an ID
00892   int dbTag = this->getDbTag();
00893   int i, j , k;
00894   int loc = 0;
00895   
00896   static ID idData(11);  
00897   idData(0) = this->getTag();
00898   idData(1) = connectedExternalNodes(0);
00899   idData(2) = connectedExternalNodes(1);
00900   idData(3) = theCoordTransf->getClassTag();
00901   int theCoordTransfDbTag  = theCoordTransf->getDbTag();
00902   if (theCoordTransfDbTag  == 0) {
00903     theCoordTransfDbTag = theChannel.getDbTag();
00904     if (theCoordTransfDbTag  != 0) 
00905       theCoordTransf->setDbTag(theCoordTransfDbTag);
00906   }
00907   idData(4) = theCoordTransfDbTag;
00908 
00909   idData(5) = initialFlag;
00910   idData(6) = maxIter;
00911 
00912   loc = 7;
00913   for (i = 0; i<2; i++) {
00914     int sectClassTag = section[i]->getClassTag();
00915     int sectDbTag = section[i]->getDbTag();
00916     if (sectDbTag == 0) {
00917       sectDbTag = theChannel.getDbTag();
00918       section[i]->setDbTag(sectDbTag);
00919     }
00920 
00921     idData(loc) = sectClassTag;
00922     idData(loc+1) = sectDbTag;
00923     loc += 2;
00924   }  
00925 
00926   if (theChannel.sendID(dbTag, commitTag, idData) < 0) {
00927     opserr << "NLBeamColumn3d::sendSelf() - failed to send ID data\n";
00928     return -1;
00929   }    
00930 
00931   // send the coordinate transformation
00932   
00933   if (theCoordTransf->sendSelf(commitTag, theChannel) < 0) {
00934     opserr << "NLBeamColumn3d::sendSelf() - failed to send crdTranf\n";
00935     return -1;
00936   }      
00937 
00938   //
00939   // send the sections
00940   //
00941   
00942   for (j = 0; j<2; j++) {
00943     if (section[j]->sendSelf(commitTag, theChannel) < 0) {
00944       opserr << "NLBeamColumn3d::sendSelf() - section " << j << " failed to send itself\n";
00945       return -1;
00946     }
00947   }
00948   
00949   // into a vector place distrLoadCommit, rho, UeCommit, Secommit and kvcommit
00950   int secDefSize = 0;
00951   for (i = 0; i < 2; i++) {
00952      int size = section[i]->getOrder();
00953      secDefSize   += size;
00954   }
00955 
00956   Vector dData(10+6+36+secDefSize); 
00957   loc = 0;
00958 
00959   // place double variables into Vector
00960   dData(loc++) = E;
00961   dData(loc++) = A;
00962   dData(loc++) = Iz;
00963   dData(loc++) = Iy;
00964   dData(loc++) = G;
00965   dData(loc++) = J;
00966   dData(loc++) = beta1;
00967   dData(loc++) = beta2;
00968   dData(loc++) = rho;
00969   dData(loc++) = tolerance;
00970   
00971   // place kvcommit into vector
00972   for (i=0; i<6; i++) 
00973     dData(loc++) = qCommit(i);
00974 
00975   // place kvcommit into vector
00976   for (i=0; i<6; i++) 
00977      for (j=0; j<6; j++)
00978         dData(loc++) = kbCommit(i,j);
00979 
00980   // place vscommit into vector
00981   for (k=0; k<2; k++)
00982     for (i=0; i<section[k]->getOrder(); i++) 
00983         dData(loc++) = (eCommit[k])(i);
00984 
00985   if (theChannel.sendVector(dbTag, commitTag, dData) < 0) {
00986      opserr << "NLBeamColumn3d::sendSelf() - failed to send Vector data\n";
00987      return -1;
00988   }    
00989 
00990   return 0;
00991 }
00992 
00993 int 
00994 BeamWithHinges3d::recvSelf(int commitTag, Channel &theChannel,
00995                                FEM_ObjectBroker &theBroker)
00996 {
00997   // place the integer data into an ID
00998   int dbTag = this->getDbTag();
00999   int i, j , k;
01000   int loc = 0;
01001   
01002   static ID idData(11);  
01003 
01004   if (theChannel.recvID(dbTag, commitTag, idData) < 0)  {
01005     opserr << "NLBeamColumn3d::recvSelf() - failed to recv ID data\n";
01006     return -1;
01007   }    
01008 
01009   this->setTag(idData(0));
01010   connectedExternalNodes(0) = idData(1);
01011   connectedExternalNodes(1) = idData(2);
01012 
01013   maxIter = idData(5);
01014   initialFlag = idData(6);
01015   
01016   int crdTransfClassTag = idData(3);
01017   int crdTransfDbTag = idData(4);
01018 
01019   // create a new crdTransf object if one needed
01020   if (theCoordTransf == 0 || theCoordTransf->getClassTag() != crdTransfClassTag) {
01021       if (theCoordTransf != 0)
01022           delete theCoordTransf;
01023 
01024       theCoordTransf = theBroker.getNewCrdTransf3d(crdTransfClassTag);
01025 
01026       if (theCoordTransf == 0) {
01027         opserr << "NLBeamColumn3d::recvSelf() - failed to obtain a CrdTrans object with classTag " <<
01028                                 crdTransfClassTag << endln;
01029           return -2;      
01030       }
01031   }
01032 
01033   theCoordTransf->setDbTag(crdTransfDbTag);
01034 
01035   // invoke recvSelf on the crdTransf obkject
01036   if (theCoordTransf->recvSelf(commitTag, theChannel, theBroker) < 0)  
01037   {
01038      opserr << "NLBeamColumn3d::sendSelf() - failed to recv crdTranf\n";
01039      return -3;
01040   }      
01041 
01042   //
01043   // receive the sections
01044   //
01045 
01046   loc = 7;
01047   if (section[0] == 0) {
01048 
01049     // if no sections yet created, we create new ones and then do a recvSelf
01050     for (i=0; i<2; i++) {
01051       int sectClassTag = idData(loc);
01052       int sectDbTag = idData(loc+1);
01053       loc += 2;
01054       section[i] = theBroker.getNewSection(sectClassTag);
01055       if (section[i] == 0) {
01056         opserr << "NLBeamColumn3d::recvSelf() - Broker could not create Section of class type" << sectClassTag << endln;
01057         exit(-1);
01058       }
01059       section[i]->setDbTag(sectDbTag);
01060       if (section[i]->recvSelf(commitTag, theChannel, theBroker) < 0) {
01061         opserr << "NLBeamColumn3d::recvSelf() - section " << i << " failed to recv itself\n";
01062         return -1;
01063       }     
01064     }
01065 
01066     this->setHinges();
01067 
01068   } else {
01069 
01070     // if sections exist, we ensure of correct type and then do a recvSelf
01071     for (i=0; i<2; i++) {
01072 
01073       int sectClassTag = idData(loc);
01074       int sectDbTag = idData(loc+1);
01075       loc += 2;
01076 
01077       // check of correct type
01078       if (section[i]->getClassTag() !=  sectClassTag) {
01079         // delete the old section[i] and create a new one
01080         delete section[i];
01081         section[i] = theBroker.getNewSection(sectClassTag);
01082         if (section[i] == 0) {
01083           opserr << "NLBeamColumn3d::recvSelf() - Broker could not create Section of class type" << sectClassTag << endln;
01084           exit(-1);
01085         }
01086       }
01087 
01088       // recvvSelf on it
01089       section[i]->setDbTag(sectDbTag);
01090       if (section[i]->recvSelf(commitTag, theChannel, theBroker) < 0) {
01091         opserr << "NLBeamColumn3d::recvSelf() - section " <<
01092                                 i << "failed to recv itself\n";
01093         return -1;
01094       }     
01095     }
01096   }
01097 
01098 
01099   // into a vector place distrLoadCommit, rho, UeCommit, Secommit and kvcommit
01100   int secDefSize = 0;
01101   for (i = 0; i < 2; i++) {
01102      int size = section[i]->getOrder();
01103      secDefSize   += size;
01104   }
01105 
01106   Vector dData(10+6+36+secDefSize); 
01107   loc = 0;
01108 
01109   if (theChannel.recvVector(dbTag, commitTag, dData) < 0) {
01110      opserr << "NLBeamColumn3d::sendSelf() - failed to send Vector data\n";
01111      return -1;
01112   }    
01113 
01114   // place double variables into Vector
01115    E = dData(loc++);
01116    A = dData(loc++);
01117    Iz = dData(loc++);
01118    Iy = dData(loc++);
01119    G = dData(loc++);
01120    J = dData(loc++);
01121    beta1 = dData(loc++);
01122    beta2 = dData(loc++);
01123    rho = dData(loc++);
01124    tolerance = dData(loc++);
01125   
01126   // place kvcommit into vector
01127   for (i=0; i<6; i++) 
01128     qCommit(i) = dData(loc++);
01129 
01130   // place kvcommit into vector
01131   for (i=0; i<6; i++) 
01132      for (j=0; j<6; j++)
01133         kbCommit(i,j) = dData(loc++);;
01134 
01135   // place vscommit into vector
01136   for (k=0; k<2; k++) 
01137     for (i=0; i<section[k]->getOrder(); i++) 
01138        (eCommit[k])(i) = dData(loc++);
01139 
01140   initialFlag = 2;
01141 
01142   return 0;
01143 }
01144 
01145 void 
01146 BeamWithHinges3d::Print(OPS_Stream &s, int flag)
01147 {
01148   s << "\nBeamWithHinges3d, tag: " << this->getTag() << endln;
01149   s << "\tConnected Nodes: " << connectedExternalNodes;
01150   s << "\tE:  " << E << endln;
01151   s << "\tA:  " << A << endln;
01152   s << "\tIz: " << Iz << endln;
01153   s << "\tIy: " << Iy << endln;
01154   s << "\tG:  " << G << endln;
01155   s << "\tJ:  " << J << endln;
01156   
01157   double P, Mz1, Mz2, Vy, My1, My2, Vz, T;
01158   double L = theCoordTransf->getInitialLength();
01159   double oneOverL = 1.0/L;
01160 
01161   P   = qCommit(0);
01162   Mz1 = qCommit(1);
01163   Mz2 = qCommit(2);
01164   Vy  = (Mz1+Mz2)*oneOverL;
01165   My1 = qCommit(3);
01166   My2 = qCommit(4);
01167   Vz  = (My1+My2)*oneOverL;
01168   T   = qCommit(5);
01169 
01170   s << "\tEnd 1 Forces (P Mz Vy My Vz T): "
01171     << -P+p0[0] << ' ' << Mz1 << ' ' <<  Vy+p0[1] << ' ' << My1 << ' ' <<  Vz+p0[3] << ' ' << -T << endln;
01172   s << "\tEnd 2 Forces (P Mz Vy My Vz T): "
01173     <<  P << ' ' << Mz2 << ' ' << -Vy+p0[2] << ' ' << My2 << ' ' << -Vz+p0[4] << ' ' <<  T << endln;
01174   
01175   if (section[0] != 0) {
01176     s << "Hinge 1, section tag: " << section[0]->getTag() << 
01177       ", length: " << beta1*L << endln;
01178     section[0]->Print(s,flag);
01179   }
01180   
01181   if (section[1] != 0) {
01182     s << "Hinge 2, section tag: " << section[2]->getTag() << 
01183       ", length: " << beta2*L << endln;
01184     section[1]->Print(s,flag);
01185   }
01186 }
01187 
01189 //Private Function Definitions
01190 
01191 void 
01192 BeamWithHinges3d::setNodePtrs(Domain *theDomain)
01193 {
01194   theNodes[0] = theDomain->getNode(connectedExternalNodes(0));
01195   theNodes[1] = theDomain->getNode(connectedExternalNodes(1));
01196   
01197   if(theNodes[0] == 0) {
01198     opserr << "BeamWithHinges3d::setNodePtrs() -- node 1 does not exist\n";
01199     exit(-1);
01200   }
01201   
01202   if(theNodes[1] == 0) {
01203     opserr << "BeamWithHinges3d::setNodePtrs() -- node 2 does not exist\n";
01204     exit(-1);
01205   }
01206   
01207   // check for correct # of DOF's
01208   int dofNd1 = theNodes[0]->getNumberDOF();
01209   int dofNd2 = theNodes[1]->getNumberDOF();
01210   if ((dofNd1 != 6) || (dofNd2 != 6))  {
01211     opserr << "BeamWithHinges3d::setNodePtrs() -- nodal dof is not three\n";
01212     exit(-1);          
01213   }
01214 }
01215 
01216 int
01217 BeamWithHinges3d::update(void)
01218 {
01219   // if have completed a recvSelf() - do a revertToLastCommit
01220   // to get e, kb, etc. set correctly
01221   if (initialFlag == 2)
01222     this->revertToLastCommit();
01223 
01224   // Update the coordinate transformation
01225   theCoordTransf->update();
01226   
01227   // Convert to basic system from local coord's (eliminate rb-modes)
01228   static Vector v(6);                           // basic system deformations
01229   v = theCoordTransf->getBasicTrialDisp();
01230   
01231   static Vector dv(6);
01232   dv = theCoordTransf->getBasicIncrDeltaDisp();
01233   
01234   double L = theCoordTransf->getInitialLength();
01235   double oneOverL = 1.0/L;
01236 
01237   // Section locations along element length ...
01238   double xi[2];
01239   // and their integration weights
01240   double lp[2];
01241   
01242   lp[0] = beta1*L;
01243   lp[1] = beta2*L;
01244 
01245   xi[0] = 0.5*lp[0];
01246   xi[1] = L-0.5*lp[1];
01247   
01248   // element properties
01249   static Matrix f(6,6); // element flexibility
01250   static Vector vr(6);  // Residual element deformations
01251   
01252   static Matrix Iden(6,6);   // an identity matrix for matrix inverse
01253   Iden.Zero();
01254   for (int i = 0; i < 6; i++)
01255     Iden(i,i) = 1.0;
01256 
01257   // Length of elastic interior
01258   double Le = L-lp[0]-lp[1];
01259   double LoverEA   = Le/(E*A);
01260   double Lover3EIz = Le/(3*E*Iz);
01261   double Lover6EIz = 0.5*Lover3EIz;
01262   double Lover3EIy = Le/(3*E*Iy);
01263   double Lover6EIy = 0.5*Lover3EIy;
01264   double LoverGJ   = Le/(G*J);
01265 
01266   // Elastic flexibility of element interior
01267   static Matrix fe(4,4);
01268   fe(0,0) = fe(1,1) =  Lover3EIz;
01269   fe(0,1) = fe(1,0) = -Lover6EIz;
01270   fe(2,2) = fe(3,3) =  Lover3EIy;
01271   fe(2,3) = fe(3,2) = -Lover6EIy;
01272   
01273   // Equilibrium transformation matrix
01274   static Matrix B(4,4);
01275   B(0,0) = B(2,2) = 1.0 - beta1;
01276   B(1,1) = B(3,3) = 1.0 - beta2;
01277   B(0,1) = B(2,3) = -beta1;
01278   B(1,0) = B(3,2) = -beta2;
01279   
01280   // Transform the elastic flexibility of the element
01281   // interior to the basic system
01282   static Matrix fElastic(4,4);
01283   fElastic.addMatrixTripleProduct(0.0, B, fe, 1.0);
01284 
01285   // calculate nodal force increments and update nodal forces
01286   static Vector dq(6);
01287   //dq = kb * dv;   // using previous stiff matrix k,i
01288   dq.addMatrixVector(0.0, kb, dv, 1.0);
01289   
01290   for (int j = 0; j < maxIter; j++) {
01291     
01292     // q += dq;
01293     q.addVector(1.0, dq, 1.0);
01294     
01295     // Set element flexibility to flexibility of elastic region
01296     f.Zero();
01297     f(0,0) = LoverEA;
01298     f(1,1) = fElastic(0,0);
01299     f(2,2) = fElastic(1,1);
01300     f(1,2) = fElastic(0,1);
01301     f(2,1) = fElastic(1,0);
01302     f(3,3) = fElastic(2,2);
01303     f(4,4) = fElastic(3,3);
01304     f(3,4) = fElastic(2,3);
01305     f(4,3) = fElastic(3,2);
01306     f(5,5) = LoverGJ;    
01307 
01308     // vr = fElastic * q;
01309     vr(0) = LoverEA*q(0) + v0[0];
01310     vr(1) = fElastic(0,0)*q(1) + fElastic(0,1)*q(2) + v0[1];
01311     vr(2) = fElastic(1,0)*q(1) + fElastic(1,1)*q(2) + v0[2];
01312     vr(3) = fElastic(2,2)*q(3) + fElastic(2,3)*q(4) + v0[3];
01313     vr(4) = fElastic(3,2)*q(3) + fElastic(3,3)*q(4) + v0[4];
01314     vr(5) = LoverGJ*q(5);
01315 
01316     for (int i = 0; i < 2; i++) {
01317       
01318       if (section[i] == 0 || lp[i] <= 0.0)
01319         continue;
01320       
01321       // Get section information
01322       int order = section[i]->getOrder();
01323       const ID &code = section[i]->getType();
01324       
01325       Vector s(workArea, order);
01326       Vector ds(&workArea[order], order);
01327       Vector de(&workArea[2*order], order);
01328       
01329       Matrix fb(&workArea[3*order], order, 6);
01330       
01331       double xL = xi[i]*oneOverL;
01332       double xL1 = xL-1.0;
01333       
01334       int ii;
01335       // Section forces
01336       // s = b*q + bp*currDistrLoad;
01337       //this->getForceInterpMatrix(b, xi[i], code);
01338       //s.addMatrixVector(0.0, b, q, 1.0);
01339       for (ii = 0; ii < order; ii++) {
01340         switch(code(ii)) {
01341         case SECTION_RESPONSE_P:
01342           s(ii) = q(0);
01343           break;
01344         case SECTION_RESPONSE_MZ:
01345           s(ii) = xL1*q(1) + xL*q(2);
01346           break;
01347         case SECTION_RESPONSE_VY:
01348           s(ii) = oneOverL*(q(1)+q(2));
01349           break;
01350         case SECTION_RESPONSE_MY:
01351           s(ii) = xL1*q(3) + xL*q(4);
01352           break;
01353         case SECTION_RESPONSE_VZ:
01354           s(ii) = oneOverL*(q(3)+q(4));
01355           break;
01356         case SECTION_RESPONSE_T:
01357           s(ii) = q(5);
01358           break;
01359         default:
01360           s(ii) = 0.0;
01361           break;
01362         }
01363       }
01364 
01365       // Add the effects of element loads, if present
01366       if (sp != 0) {
01367         const Matrix &s_p = *sp;
01368         for (ii = 0; ii < order; ii++) {
01369           switch(code(ii)) {
01370           case SECTION_RESPONSE_P:
01371             s(ii) += s_p(0,i);
01372             break;
01373           case SECTION_RESPONSE_MZ:
01374             s(ii) += s_p(1,i);
01375             break;
01376           case SECTION_RESPONSE_VY:
01377             s(ii) += s_p(2,i);
01378             break;
01379           case SECTION_RESPONSE_MY:
01380             s(ii) += s_p(3,i);
01381             break;
01382           case SECTION_RESPONSE_VZ:
01383             s(ii) += s_p(4,i);
01384             break;
01385           default:
01386             break;
01387           }
01388         }
01389       }
01390       
01391       // Increment in section forces
01392       // ds = s - sr
01393       ds = s;
01394       ds.addVector(1.0, sr[i], -1.0);
01395       
01396       // compute section deformation increments and update current deformations
01397       // e += fs * ds;
01398       de.addMatrixVector(0.0, fs[i], ds, 1.0);
01399       if (initialFlag != 0)
01400         e[i].addVector(1.0, de, 1.0);
01401       
01402       // set section deformations
01403       section[i]->setTrialSectionDeformation(e[i]);
01404       
01405       // get section resisting forces
01406       sr[i] = section[i]->getStressResultant();
01407       
01408       // get section flexibility matrix
01409       fs[i] = section[i]->getSectionFlexibility();
01410       
01411       // ds = s - sr;
01412       ds = s;
01413       ds.addVector(1.0, sr[i], -1.0);
01414       
01415       de.addMatrixVector(0.0, fs[i], ds, 1.0);
01416       
01417       // integrate section flexibility matrix
01418       // f += (b^ fs * b) * lp[i];
01419       //f.addMatrixTripleProduct(1.0, b, fSec, lp[i]);
01420       int jj;
01421       fb.Zero();
01422       double tmp;
01423       const Matrix &fSec = fs[i];
01424       for (ii = 0; ii < order; ii++) {
01425         switch(code(ii)) {
01426         case SECTION_RESPONSE_P:
01427           for (jj = 0; jj < order; jj++)
01428             fb(jj,0) += fSec(jj,ii)*lp[i];
01429           break;
01430         case SECTION_RESPONSE_MZ:
01431           for (jj = 0; jj < order; jj++) {
01432             tmp = fSec(jj,ii)*lp[i];
01433             fb(jj,1) += xL1*tmp;
01434             fb(jj,2) += xL*tmp;
01435           }
01436           break;
01437         case SECTION_RESPONSE_VY:
01438           for (jj = 0; jj < order; jj++) {
01439             //tmp = oneOverL*fSec(jj,ii)*lp[i]*L/lp[i];
01440             tmp = fSec(jj,ii);
01441             fb(jj,1) += tmp;
01442             fb(jj,2) += tmp;
01443           }
01444           break;
01445         case SECTION_RESPONSE_MY:
01446           for (jj = 0; jj < order; jj++) {
01447             tmp = fSec(jj,ii)*lp[i];
01448             fb(jj,3) += xL1*tmp;
01449             fb(jj,4) += xL*tmp;
01450           }
01451           break;
01452         case SECTION_RESPONSE_VZ:
01453           for (jj = 0; jj < order; jj++) {
01454             //tmp = oneOverL*fSec(jj,ii)*lp[i]*L/lp[i];
01455             tmp = fSec(jj,ii);
01456             fb(jj,3) += tmp;
01457             fb(jj,4) += tmp;
01458           }
01459           break;
01460         case SECTION_RESPONSE_T:
01461           for (jj = 0; jj < order; jj++)
01462             fb(jj,5) += fSec(jj,ii)*lp[i];
01463           break;
01464         default:
01465           break;
01466         }
01467       }
01468       for (ii = 0; ii < order; ii++) {
01469         switch (code(ii)) {
01470         case SECTION_RESPONSE_P:
01471           for (jj = 0; jj < 6; jj++)
01472             f(0,jj) += fb(ii,jj);
01473           break;
01474         case SECTION_RESPONSE_MZ:
01475           for (jj = 0; jj < 6; jj++) {
01476             tmp = fb(ii,jj);
01477             f(1,jj) += xL1*tmp;
01478             f(2,jj) += xL*tmp;
01479           }
01480           break;
01481         case SECTION_RESPONSE_VY:
01482           for (jj = 0; jj < 6; jj++) {
01483             tmp = oneOverL*fb(ii,jj);
01484             f(1,jj) += tmp;
01485             f(2,jj) += tmp;
01486           }
01487           break;
01488         case SECTION_RESPONSE_MY:
01489           for (jj = 0; jj < 6; jj++) {
01490             tmp = fb(ii,jj);
01491             f(3,jj) += xL1*tmp;
01492             f(4,jj) += xL*tmp;
01493           }
01494           break;
01495         case SECTION_RESPONSE_VZ:
01496           for (jj = 0; jj < 6; jj++) {
01497             tmp = oneOverL*fb(ii,jj);
01498             f(3,jj) += tmp;
01499             f(4,jj) += tmp;
01500           }
01501           break;
01502         case SECTION_RESPONSE_T:
01503           for (jj = 0; jj < 6; jj++)
01504             f(5,jj) += fb(ii,jj);
01505           break;
01506         default:
01507           break;
01508         }
01509       }
01510       
01511       // UNCOMMENT WHEN DISTRIBUTED LOADS ARE ADDED TO INTERFACE
01512       // vr.addMatrixVector(1.0, vElastic, currDistrLoad, 1.0);
01513       
01514       // vr += (b^ (e+de)) * lp[i];
01515       de.addVector(1.0, e[i], 1.0);
01516       //vr.addMatrixTransposeVector(1.0, b, de, lp[i]);
01517       for (ii = 0; ii < order; ii++) {
01518         switch(code(ii)) {
01519         case SECTION_RESPONSE_P:
01520           vr(0) += de(ii)*lp[i];
01521           break;
01522         case SECTION_RESPONSE_MZ:
01523           tmp = de(ii)*lp[i];
01524           vr(1) += xL1*tmp; vr(2) += xL*tmp;
01525           break;
01526         case SECTION_RESPONSE_VY:
01527           //tmp = oneOverL*de(ii)*lp[i]*L/lp[i];
01528           tmp = de(ii);
01529           vr(1) += tmp; vr(2) += tmp;
01530           break;
01531         case SECTION_RESPONSE_MY:
01532           tmp = de(ii)*lp[i];
01533           vr(3) += xL1*tmp; vr(4) += xL*tmp;
01534           break;
01535         case SECTION_RESPONSE_VZ:
01536           //tmp = oneOverL*de(ii)*lp[i]*L/lp[i];
01537           tmp = de(ii);
01538           vr(3) += tmp; vr(4) += tmp;
01539           break;
01540         case SECTION_RESPONSE_T:
01541           vr(5) += de(ii)*lp[i];
01542           break;
01543         default:
01544           break;
01545         }
01546       }
01547     }
01548     
01549     // calculate element stiffness matrix
01550     if (f.Solve(Iden,kb) < 0)
01551       opserr << "BeamWithHinges3d::update() -- could not invert flexibility\n";
01552                               
01553 
01554     // dv = v - vr;
01555     dv = v;
01556     dv.addVector(1.0, vr, -1.0);
01557     
01558     // determine resisting forces
01559     // dq = kb * dv;
01560     dq.addMatrixVector(0.0, kb, dv, 1.0);
01561     
01562     double dW = dv^ dq;
01563     
01564     if (fabs(dW) < tolerance)
01565       break;
01566   }
01567   
01568   // q += dq;
01569   q.addVector(1.0, dq, 1.0);
01570   
01571   initialFlag = 1;
01572   
01573   return 0;
01574 }
01575 
01576 void
01577 BeamWithHinges3d::setHinges(void)
01578 {
01579   for (int i = 0; i < 2; i++) {
01580     if (section[i] == 0)
01581       continue;
01582     
01583     // Get the number of section response quantities
01584     int order = section[i]->getOrder();
01585     
01586     fs[i] = Matrix(order,order);
01587     e[i]  = Vector(order);
01588     sr[i] = Vector(order);
01589     eCommit[i] = Vector(order);    
01590   }
01591 }
01592 
01593 void
01594 BeamWithHinges3d::getForceInterpMatrix(Matrix &b, double x, const ID &code)
01595 {                       
01596   b.Zero();
01597   
01598   double L = theCoordTransf->getInitialLength();
01599   double xi = x/L;
01600   
01601   for (int i = 0; i < code.Size(); i++) {
01602     switch (code(i)) {
01603     case SECTION_RESPONSE_MZ:           // Moment, Mz, interpolation
01604       b(i,1) = xi - 1.0;
01605       b(i,2) = xi;
01606       break;
01607     case SECTION_RESPONSE_P:            // Axial, P, interpolation
01608       b(i,0) = 1.0;
01609       break;
01610     case SECTION_RESPONSE_VY:           // Shear, Vy, interpolation
01611       b(i,1) = b(i,2) = 1.0/L;
01612       break;
01613     case SECTION_RESPONSE_MY:           // Moment, My, interpolation
01614       b(i,3) = xi - 1.0;
01615       b(i,4) = xi;
01616       break;
01617     case SECTION_RESPONSE_VZ:           // Shear, Vz, interpolation
01618       b(i,3) = b(i,4) = 1.0/L;
01619       break;
01620     case SECTION_RESPONSE_T:            // Torsion, T, interpolation
01621       b(i,5) = 1.0;
01622       break;
01623     default:
01624       break;
01625     }
01626   }
01627 }
01628 
01629 void
01630 BeamWithHinges3d::getDistrLoadInterpMatrix(Matrix &bp, double x, const ID & code)
01631 {
01632   bp.Zero();
01633 
01634   double L = theCoordTransf->getInitialLength();
01635   double xi = x/L;
01636   
01637   for (int i = 0; i < code.Size(); i++) {
01638     switch (code(i)) {
01639     case SECTION_RESPONSE_MZ:           // Moment, Mz, interpolation
01640       bp(i,1) = 0.5*xi*(xi-1);
01641       break;
01642     case SECTION_RESPONSE_P:            // Axial, P, interpolation
01643       bp(i,0) = 1.0-xi;
01644       break;
01645     case SECTION_RESPONSE_VY:           // Shear, Vy, interpolation
01646       bp(i,1) = xi-0.5;
01647       break;
01648     case SECTION_RESPONSE_MY:           // Moment, My, interpolation
01649       bp(i,2) = 0.5*xi*(xi-1);
01650       break;
01651     case SECTION_RESPONSE_VZ:           // Shear, Vz, interpolation
01652       bp(i,2) = xi-0.5;
01653       break;
01654     case SECTION_RESPONSE_T:            // Torsion, T, interpolation
01655       bp(i,3) = 1.0-xi;
01656       break;
01657     default:
01658       break;
01659     }
01660   }
01661 }
01662 
01663 Response*
01664 BeamWithHinges3d::setResponse(const char **argv, int argc, Information &info)
01665 {
01666   // hinge rotations
01667   if (strcmp(argv[0],"plasticDeformation") == 0 ||
01668       strcmp(argv[0],"plasticRotation") == 0)
01669     return new ElementResponse(this, 1, Vector(3));
01670   
01671   // global forces
01672   else if (strcmp(argv[0],"force") == 0 || strcmp(argv[0],"forces") == 0 ||
01673            strcmp(argv[0],"globalForce") == 0 || strcmp(argv[0],"globalForces") == 0)
01674     return new ElementResponse(this, 2, theVector);
01675   
01676   // stiffness
01677   else if (strcmp(argv[0],"stiffness") == 0)
01678     return new ElementResponse(this, 3, theMatrix);
01679   
01680   // local forces
01681   else if (strcmp(argv[0],"localForce") == 0 || strcmp(argv[0],"localForces") == 0)
01682     return new ElementResponse(this, 4, theVector);
01683   
01684   // section response
01685   else if (strcmp(argv[0],"section") == 0) {
01686     int sectionNum = atoi(argv[1]) - 1;
01687     
01688     if (sectionNum >= 0 && sectionNum < 2)
01689       if (section[sectionNum] != 0)
01690         return section[sectionNum]->setResponse(&argv[2], argc-2, info);
01691     return 0;
01692   }
01693   else
01694     return 0;
01695 }
01696 
01697 int
01698 BeamWithHinges3d::getResponse(int responseID, Information &eleInfo)
01699 {
01700   double V, N, T, M1, M2;
01701   double L = theCoordTransf->getInitialLength();
01702   static Vector force(12);
01703   static Vector def(6);
01704   
01705   switch (responseID) {
01706   case 1: {
01707     const Vector &v = theCoordTransf->getBasicTrialDisp();
01708     double LoverEA   = L/(E*A);
01709     double Lover3EIz = L/(3*E*Iz);
01710     double Lover6EIz = 0.5*Lover3EIz;
01711     double LoverGJ   = L/(G*J);
01712     double Lover3EIy = L/(3*E*Iy);
01713     double Lover6EIy = 0.5*Lover3EIy;
01714 
01715     double q1 = qCommit(1);
01716     double q2 = qCommit(2);
01717     double q3 = qCommit(3);
01718     double q4 = qCommit(4);
01719 
01720     def(0) = v(0) - LoverEA*qCommit(0);
01721     def(1) = v(1) - Lover3EIz*q1 + Lover6EIz*q2;
01722     def(2) = v(2) + Lover6EIz*q1 - Lover3EIz*q2;
01723     def(3) = v(3) - Lover3EIy*q3 + Lover6EIy*q4;
01724     def(4) = v(4) + Lover6EIy*q3 - Lover3EIy*q4;
01725     def(5) = v(5) - LoverGJ*qCommit(5);
01726 
01727     return eleInfo.setVector(def);
01728   }
01729   
01730   case 2: // global forces
01731     return eleInfo.setVector(this->getResistingForce());
01732     
01733   case 3: // stiffness
01734     return eleInfo.setMatrix(this->getTangentStiff());
01735     
01736   case 4: // local forces
01737     // Axial
01738     N = q(0);
01739     force(6) =  N;
01740     force(0) = -N+p0[0];
01741     
01742     // Torsion
01743     T = q(5);
01744     force(9) =  T;
01745     force(3) = -T;
01746     
01747     // Moments about z and shears along y
01748     M1 = q(1);
01749     M2 = q(2);
01750     force(5)  = M1;
01751     force(11) = M2;
01752     V = (M1+M2)/L;
01753     force(1) =  V+p0[1];
01754     force(7) = -V+p0[2];
01755     
01756     // Moments about y and shears along z
01757     M1 = q(3);
01758     M2 = q(4);
01759     force(4)  = M1;
01760     force(10) = M2;
01761     V = (M1+M2)/L;
01762     force(2) = -V+p0[3];
01763     force(8) =  V+p0[4];
01764 
01765     return eleInfo.setVector(force);
01766     
01767   default:
01768     return -1;
01769   }
01770 }
01771 
01772 int
01773 BeamWithHinges3d::displaySelf(Renderer &theViewer, int displayMode, float fact)
01774 {
01775   // first determine the end points of the quad based on
01776   // the display factor (a measure of the distorted image)
01777   const Vector &end1Crd = theNodes[0]->getCrds();
01778   const Vector &end2Crd = theNodes[1]->getCrds();       
01779   
01780   const Vector &end1Disp = theNodes[0]->getDisp();
01781   const Vector &end2Disp = theNodes[1]->getDisp();
01782   
01783   static Vector v1(3);
01784   static Vector v2(3);
01785   
01786   for (int i = 0; i < 3; i++) {
01787     v1(i) = end1Crd(i) + end1Disp(i)*fact;
01788     v2(i) = end2Crd(i) + end2Disp(i)*fact;    
01789   }
01790   
01791   return theViewer.drawLine (v1, v2, 1.0, 1.0);
01792 }
01793 
01794 int
01795 BeamWithHinges3d::setParameter(const char **argv, int argc, Information &info)
01796 {
01797   // E of the beam interior
01798   if (strcmp(argv[0],"E") == 0) {
01799     info.theType = DoubleType;
01800     return 1;
01801   }
01802   
01803   // A of the beam interior
01804   else if (strcmp(argv[0],"A") == 0) {
01805     info.theType = DoubleType;
01806     return 3;
01807   }
01808   
01809   // I of the beam interior
01810   else if (strcmp(argv[0],"Iz") == 0) {
01811     info.theType = DoubleType;
01812     return 4;
01813   }
01814   
01815   // Section parameter
01816   else if (strcmp(argv[0],"section") ==0) {
01817     if (argc <= 2)
01818       return -1;
01819     
01820     int sectionNum = atoi(argv[1]);
01821     
01822     int ok = -1;
01823     
01824     if (sectionNum == 1)
01825       ok = section[0]->setParameter (&argv[2], argc-2, info);
01826     if (sectionNum == 2)
01827       ok = section[1]->setParameter (&argv[2], argc-2, info);
01828     
01829     if (ok < 0)
01830       return -1;
01831     else if (ok < 100)
01832       return sectionNum*100 + ok;
01833     else 
01834       return -1;
01835   }
01836   
01837   // Unknown parameter
01838   else
01839     return -1;
01840 }       
01841 
01842 int
01843 BeamWithHinges3d::updateParameter(int parameterID, Information &info)
01844 {
01845   switch (parameterID) {
01846   case 1:
01847     this->E = info.theDouble;
01848     return 0;
01849   case 3:
01850     this->A = info.theDouble;
01851     return 0;
01852   case 4:
01853     this->Iz = info.theDouble;
01854     return 0;
01855   default:
01856     if (parameterID >= 100) { // section quantity
01857       int sectionNum = parameterID/100; 
01858       if (sectionNum == 1)
01859         return section[0]->updateParameter (parameterID-100, info);
01860       if (sectionNum == 2)
01861         return section[1]->updateParameter (parameterID-2*100, info);
01862       else
01863         return -1;
01864     }
01865     else // unknown
01866       return -1;
01867   }     
01868 }       

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