NLBeamColumn3d.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.25 $
00022 // $Date: 2003/05/15 21:30:21 $
00023 // $Source: /usr/local/cvs/OpenSees/SRC/element/nonlinearBeamColumn/element/NLBeamColumn3d.cpp,v $
00024                                                                         
00025                                                                         
00026 // Written: Remo Magalhaes de Souza (rmsouza.ce.berkeley.edu) on 03/99 
00027 // Revised: rms 06/99 (mass matrix)
00028 //          rms 07/99 (using setDomain)
00029 //          rms 08/99 (included P-Delta effect)
00030 //          fmk 10/99 setResponse() & getResponse()
00031 //          rms 11/99 (included rigid joint offsets)
00032 //          rms 04/00 (using transformation class w/ linear or corotational transf)
00033 //          rms 04/00 (generalized to iterative/non-iterative algorithm)
00034 //          mhs 06/00 (using new section class w/ variable dimensions)
00035 //          rms 06/00 (torsional stiffness considered at the section level)
00036 //          rms 06/00 (making copy of the sections)
00037 //          rms 06/00 (storing section history variables at the element level)
00038 //          rms 07/00 (new state determination procedure, no need to store fscommit) 
00039 //
00040 // Purpose: This file contains the implementation for the NLBeamColumn3d class.
00041 //          NLBeamColumn3d is a materially nonlinear flexibility based frame element.
00042 
00043 #include <math.h>
00044 #include <stdlib.h>
00045 #include <string.h>
00046 #include <float.h>
00047 
00048 #include <Information.h>
00049 #include <NLBeamColumn3d.h>
00050 #include <MatrixUtil.h>
00051 #include <Domain.h>
00052 #include <Channel.h>
00053 #include <FEM_ObjectBroker.h>
00054 #include <Renderer.h>
00055 #include <ElementResponse.h>
00056 #include <ElementalLoad.h>
00057 
00058 #define  NDM   3         // dimension of the problem (3d)
00059 #define  NND   6         // number of nodal dof's
00060 #define  NEGD 12         // number of element global dof's
00061 #define  NEBD  6         // number of element dof's in the basic system
00062 
00063 #define DefaultLoverGJ 1.0e-10
00064 
00065 Matrix NLBeamColumn3d::theMatrix(12,12);
00066 Vector NLBeamColumn3d::theVector(12);
00067 double NLBeamColumn3d::workArea[200];
00068 GaussLobattoQuadRule1d01 NLBeamColumn3d::quadRule;
00069 
00070 // constructor:
00071 // invoked by a FEM_ObjectBroker, recvSelf() needs to be invoked on this object.
00072 NLBeamColumn3d::NLBeamColumn3d():
00073 Element(0,ELE_TAG_NLBeamColumn3d), connectedExternalNodes(2), 
00074 nSections(0), sections(0), crdTransf(0), 
00075 rho(0), maxIters(0), tol(0), initialFlag(0), isTorsion(false),
00076 load(NEGD),
00077 kv(NEBD,NEBD), Se(NEBD), 
00078 kvcommit(NEBD,NEBD), Secommit(NEBD),
00079 fs(0), vs(0), Ssr(0), vscommit(0), sp(0), Ki(0)
00080 {
00081   p0[0] = 0.0;
00082   p0[1] = 0.0;
00083   p0[2] = 0.0;
00084   p0[3] = 0.0;
00085   p0[4] = 0.0;
00086   
00087   theNodes[0] = 0;
00088   theNodes[1] = 0;
00089 }
00090 
00091 // constructor which takes the unique element tag, sections,
00092 // and the node ID's of it's nodal end points. 
00093 // allocates the necessary space needed by each object
00094 NLBeamColumn3d::NLBeamColumn3d (int tag, int nodeI, int nodeJ, 
00095                                 int numSections, SectionForceDeformation *sectionPtrs[],
00096                                 CrdTransf3d &coordTransf, double massDensPerUnitLength,
00097                                 int maxNumIters, double tolerance):
00098 Element(tag,ELE_TAG_NLBeamColumn3d), connectedExternalNodes(2), 
00099 nSections(numSections), sections(0), crdTransf(0),
00100 rho(massDensPerUnitLength), maxIters(maxNumIters), tol(tolerance),
00101 initialFlag(0), isTorsion(false),
00102 load(NEGD), 
00103 kv(NEBD,NEBD), Se(NEBD),  
00104 kvcommit(NEBD,NEBD), Secommit(NEBD),
00105 fs(0), vs(0), Ssr(0), vscommit(0), sp(0), Ki(0)
00106 {
00107    connectedExternalNodes(0) = nodeI;
00108    connectedExternalNodes(1) = nodeJ;    
00109 
00110    // get copy of the sections
00111    
00112    if (!sectionPtrs)
00113    {
00114        opserr << "Error: NLBeamColumn3d::NLBeamColumn3d:  invalid section pointer ";
00115        exit(-1);
00116    }      
00117    
00118    sections = new SectionForceDeformation *[nSections];
00119    if (!sections)
00120    {
00121        opserr << "Error: NLBeamColumn3d::NLBeamColumn3d: could not alocate section pointer";
00122        exit(-1);
00123    }  
00124 
00125    for (int i = 0; i < nSections; i++)
00126    {
00127       if (!sectionPtrs[i])
00128       {
00129           opserr << "Error: NLBeamColumn3d::NLBeamColumn3d: section pointer " << i << endln;
00130           exit(-1);
00131       }  
00132        
00133       sections[i] = sectionPtrs[i]->getCopy();
00134       if (!sections[i])
00135       {
00136           opserr << "Error: NLBeamColumn3d::NLBeamColumn3d: could not create copy of section " << i << endln;
00137           exit(-1);
00138       }
00139 
00140           int order = sections[i]->getOrder();
00141           const ID &code = sections[i]->getType();
00142           for (int j = 0; j < order; j++) {
00143                 if (code(j) == SECTION_RESPONSE_T)
00144                         isTorsion = true;
00145           }
00146    }
00147 
00148    if (!isTorsion)
00149      opserr << "NLBeamColumn3d::NLBeamColumn3d -- no torsion detected in sections, " <<
00150        "continuing with element torsional stiffness GJ/L = " << 1.0/DefaultLoverGJ;
00151    
00152    // get copy of the transformation object   
00153    crdTransf = coordTransf.getCopy(); 
00154    if (!crdTransf)
00155    {
00156      opserr << "Error: NLBeamColumn3d::NLBeamColumn3d: could not create copy of coordinate transformation object" << endln;
00157      exit(-1);
00158    }
00159 
00160    // alocate section flexibility matrices and section deformation vectors
00161    fs  = new Matrix [nSections];
00162    if (!fs) {
00163      opserr << "NLBeamColumn3d::NLBeamColumn3d() -- failed to allocate fs array";
00164      exit(-1);
00165    }
00166    
00167    vs = new Vector [nSections];
00168    if (!vs) {
00169      opserr << "NLBeamColumn3d::NLBeamColumn3d() -- failed to allocate vs array";
00170      exit(-1);
00171    }
00172 
00173    Ssr = new Vector [nSections];
00174    if (!Ssr) {
00175      opserr << "NLBeamColumn3d::NLBeamColumn3d() -- failed to allocate Ssr array";
00176      exit(-1);
00177    }
00178  
00179    vscommit = new Vector [nSections];
00180    if (!vscommit)
00181      {
00182        opserr << "NLBeamColumn3d::NLBeamColumn3d() -- failed to allocate vscommit array";   
00183        exit(-1);
00184    }
00185 
00186   p0[0] = 0.0;
00187   p0[1] = 0.0;
00188   p0[2] = 0.0;
00189   p0[3] = 0.0;
00190   p0[4] = 0.0;
00191 
00192   theNodes[0] = 0;
00193   theNodes[1] = 0;
00194 }
00195 
00196 
00197 // ~NLBeamColumn3d():
00198 //      destructor
00199 //      delete must be invoked on any objects created by the object
00200 NLBeamColumn3d::~NLBeamColumn3d()
00201 {
00202    if (sections)
00203    {
00204       for (int i=0; i < nSections; i++)
00205          if (sections[i])
00206             delete sections[i];
00207       delete [] sections;
00208    }  
00209    
00210    if (fs) 
00211      delete [] fs;
00212 
00213    if (vs) 
00214      delete [] vs;
00215 
00216    if (Ssr) 
00217      delete [] Ssr;
00218 
00219    if (vscommit) 
00220      delete [] vscommit;
00221 
00222    if (crdTransf)
00223      delete crdTransf;   
00224 
00225    if (sp != 0)
00226      delete sp;
00227 
00228    if (Ki != 0)
00229      delete Ki;
00230 }
00231 
00232 
00233 
00234 int
00235 NLBeamColumn3d::getNumExternalNodes(void) const
00236 {
00237   return 2;
00238 }
00239 
00240 
00241 const ID &
00242 NLBeamColumn3d::getExternalNodes(void)
00243 {
00244    return connectedExternalNodes;
00245 }
00246 
00247 Node **
00248 NLBeamColumn3d::getNodePtrs(void) 
00249 {
00250   return theNodes;
00251 }
00252 
00253 int
00254 NLBeamColumn3d::getNumDOF(void) 
00255 {
00256    return NEGD;
00257 }
00258 
00259 void
00260 NLBeamColumn3d::setDomain(Domain *theDomain)
00261 {
00262    // check Domain is not null - invoked when object removed from a domain
00263    if (theDomain == 0) {
00264       theNodes[0] = 0;
00265       theNodes[1] = 0;
00266       return;
00267    }
00268 
00269    // get pointers to the nodes
00270    
00271    int Nd1 = connectedExternalNodes(0);  
00272    int Nd2 = connectedExternalNodes(1);
00273    
00274    theNodes[0] = theDomain->getNode(Nd1);
00275    theNodes[1] = theDomain->getNode(Nd2);  
00276 
00277    if (theNodes[0] == 0)
00278    {
00279       opserr << "NLBeamColumn3d::setDomain: Nd1: ";
00280       opserr << Nd1 << "does not exist in model\n";
00281       exit(0);
00282    }
00283 
00284    if (theNodes[1] == 0) 
00285    {
00286       opserr << "NLBeamColumn3d::setDomain: Nd2: ";
00287       opserr << Nd2 << "does not exist in model\n";
00288       exit(0);
00289    }
00290 
00291    // call the DomainComponent class method 
00292    this->DomainComponent::setDomain(theDomain);
00293     
00294    // ensure connected nodes have correct number of dof's
00295    int dofNode1 = theNodes[0]->getNumberDOF();
00296    int dofNode2 = theNodes[1]->getNumberDOF();
00297    
00298    if ((dofNode1 != NND) || (dofNode2 != NND))
00299    {
00300       opserr << "NLBeamColumn3d::setDomain(): Nd2 or Nd1 incorrect dof ";
00301       exit(0);
00302    }
00303    
00304 
00305    // initialize the transformation
00306    if (crdTransf->initialize(theNodes[0], theNodes[1]))
00307    {
00308       opserr << "NLBeamColumn3d::setDomain(): Error initializing coordinate transformation";  
00309       exit(0);
00310    }
00311     
00312    // get element length
00313    double L = crdTransf->getInitialLength();
00314    if (L == 0.0)
00315    {
00316       opserr << "NLBeamColumn3d::setDomain(): Zero element length:" << this->getTag();  
00317       exit(0);
00318    }
00319 
00320    if (initialFlag != 2) 
00321      this->initializeSectionHistoryVariables();
00322 }
00323 
00324 
00325 int
00326 NLBeamColumn3d::commitState()
00327 {
00328 
00329    int err = 0;
00330    int i = 0;
00331 
00332    // call element commitState to do any base class stuff
00333    if ((err = this->Element::commitState()) != 0) {
00334      opserr << "NLBeamColumn3d::commitState () - failed in base class";
00335      return err;
00336    }    
00337 
00338    do {
00339       vscommit[i] = vs[i];
00340       err = sections[i++]->commitState();  
00341    } while (err == 0 && i < nSections);
00342    
00343    if (err)
00344       return err;
00345    
00346    // commit the transformation between coord. systems
00347    if ((err = crdTransf->commitState()) != 0)
00348       return err;
00349       
00350    // commit the element variables state
00351    kvcommit = kv;
00352    Secommit = Se;
00353 
00354    return err;
00355 }
00356 
00357 
00358 int 
00359 NLBeamColumn3d::revertToLastCommit()
00360 {
00361    int err;
00362    int i = 0;
00363       
00364    do {
00365      vs[i] = vscommit[i];
00366      err = sections[i]->revertToLastCommit();
00367      
00368      sections[i]->setTrialSectionDeformation(vs[i]);        
00369      Ssr[i] = sections[i]->getStressResultant();
00370      fs[i]  = sections[i]->getSectionFlexibility();
00371       
00372      i++;
00373    } while (err == 0 && i < nSections);
00374    
00375    if (err)
00376       return err;
00377    
00378    // revert the transformation to last commit
00379    if ((err = crdTransf->revertToLastCommit()) != 0)
00380       return err;
00381      
00382    // revert the element state to last commit
00383    Se   = Secommit;
00384    kv   = kvcommit;
00385    
00386    initialFlag = 0;
00387    // return this->update();
00388 
00389    return err;
00390 }
00391 
00392 
00393 int 
00394 NLBeamColumn3d::revertToStart()
00395 {
00396    // revert the sections state to start
00397    int err;
00398    int i = 0;
00399      
00400    do {
00401       fs[i].Zero();
00402       vs[i].Zero();
00403       Ssr[i].Zero();
00404       err = sections[i++]->revertToStart();
00405  
00406    } while (err == 0 && i < nSections);
00407 
00408    if (err)
00409       return err;
00410    
00411    // revert the transformation to start
00412    if ((err = crdTransf->revertToStart()) != 0)
00413       return err;
00414   
00415    // revert the element state to start
00416    Secommit.Zero();
00417    kvcommit.Zero();
00418 
00419    Se.Zero();
00420    kv.Zero();
00421 
00422    initialFlag = 0;
00423    // this->update(); 
00424    
00425    return err;
00426 }
00427 
00428 
00429 
00430 const Matrix &
00431 NLBeamColumn3d::getTangentStiff(void)
00432 {
00433   // Will remove once we clean up the corotational 3d transformation -- MHS
00434   crdTransf->update();
00435 
00436   return crdTransf->getGlobalStiffMatrix(kv, Se);
00437 }
00438 
00439 
00440 const Matrix &
00441 NLBeamColumn3d::getInitialStiff(void)
00442 {
00443 
00444   // check for quick return
00445   if (Ki != 0)
00446     return *Ki;
00447 
00448   // get integration point positions and weights
00449   const Matrix &xi_pt = quadRule.getIntegrPointCoords(nSections);
00450   const Vector &weight = quadRule.getIntegrPointWeights(nSections);
00451   
00452   static Matrix f(NEBD,NEBD);   // element flexibility matrix
00453 
00454   static Matrix I(NEBD,NEBD);   // an identity matrix for matrix inverse
00455   int i;
00456   
00457   I.Zero();
00458   for (i=0; i<NEBD; i++)
00459     I(i,i) = 1.0;
00460   
00461   double L = crdTransf->getInitialLength();
00462   double oneOverL  = 1.0/L;
00463   
00464   // initialize f and vr for integration
00465   f.Zero();
00466 
00467   for (i=0; i<nSections; i++) {
00468     int order      = sections[i]->getOrder();
00469     const ID &code = sections[i]->getType();
00470     
00471     Vector Ss(workArea, order);
00472     Vector dSs(&workArea[order], order);
00473     Vector dvs(&workArea[2*order], order);
00474     
00475     Matrix fb(&workArea[3*order], order, NEBD);
00476         
00477     double xL  = xi_pt(i,0);
00478     double xL1 = xL-1.0;
00479     
00480     // get section flexibility matrix
00481     const Matrix &fSec = sections[i]->getInitialFlexibility();
00482     
00483     // f = f + (b^ fs * b) * weight(i);
00484     //f.addMatrixTripleProduct(1.0, b[i], fs[i], weight(i));
00485     int jj, ii;
00486     fb.Zero();
00487     double tmp;
00488     for (ii = 0; ii < order; ii++) {
00489       switch(code(ii)) {
00490       case SECTION_RESPONSE_P:
00491         for (jj = 0; jj < order; jj++)
00492           fb(jj,0) += fSec(jj,ii)*weight(i);
00493         break;
00494       case SECTION_RESPONSE_MZ:
00495         for (jj = 0; jj < order; jj++) {
00496           tmp = fSec(jj,ii)*weight(i);
00497           fb(jj,1) += xL1*tmp;
00498           fb(jj,2) += xL*tmp;
00499         }
00500         break;
00501       case SECTION_RESPONSE_VY:
00502         for (jj = 0; jj < order; jj++) {
00503           tmp = oneOverL*fSec(jj,ii)*weight(i);
00504           fb(jj,1) += tmp;
00505           fb(jj,2) += tmp;
00506         }
00507         break;
00508       case SECTION_RESPONSE_MY:
00509         for (jj = 0; jj < order; jj++) {
00510           tmp = fSec(jj,ii)*weight(i);
00511           fb(jj,3) += xL1*tmp;
00512           fb(jj,4) += xL*tmp;
00513         }
00514         break;
00515       case SECTION_RESPONSE_VZ:
00516         for (jj = 0; jj < order; jj++) {
00517           tmp = oneOverL*fSec(jj,ii)*weight(i);
00518           fb(jj,3) += tmp;
00519           fb(jj,4) += tmp;
00520         }
00521         break;
00522       case SECTION_RESPONSE_T:
00523         for (jj = 0; jj < order; jj++)
00524           fb(jj,5) += fSec(jj,ii)*weight(i);
00525         break;
00526       default:
00527         break;
00528       }
00529     }
00530     for (ii = 0; ii < order; ii++) {
00531       switch (code(ii)) {
00532       case SECTION_RESPONSE_P:
00533         for (jj = 0; jj < 6; jj++)
00534           f(0,jj) += fb(ii,jj);
00535         break;
00536       case SECTION_RESPONSE_MZ:
00537         for (jj = 0; jj < 6; jj++) {
00538           tmp = fb(ii,jj);
00539           f(1,jj) += xL1*tmp;
00540           f(2,jj) += xL*tmp;
00541         }
00542         break;
00543       case SECTION_RESPONSE_VY:
00544         for (jj = 0; jj < 6; jj++) {
00545           tmp = oneOverL*fb(ii,jj);
00546           f(1,jj) += tmp;
00547           f(2,jj) += tmp;
00548         }
00549         break;
00550       case SECTION_RESPONSE_MY:
00551         for (jj = 0; jj < 6; jj++) {
00552           tmp = fb(ii,jj);
00553           f(3,jj) += xL1*tmp;
00554           f(4,jj) += xL*tmp;
00555         }
00556         break;
00557       case SECTION_RESPONSE_VZ:
00558         for (jj = 0; jj < 6; jj++) {
00559           tmp = oneOverL*fb(ii,jj);
00560           f(3,jj) += tmp;
00561           f(4,jj) += tmp;
00562         }
00563         break;
00564       case SECTION_RESPONSE_T:
00565         for (jj = 0; jj < 6; jj++)
00566           f(5,jj) += fb(ii,jj);
00567         break;
00568       default:
00569         break;
00570       }
00571     }
00572   }
00573 
00574   f  *= L;
00575   
00576   if (!isTorsion)
00577     f(5,5) = DefaultLoverGJ;
00578   
00579   // calculate element stiffness matrix
00580   static Matrix kvInit(NEBD, NEBD);
00581   if (f.Solve(I,kvInit) < 0)
00582     opserr << "NLBeamColumn3d::updateElementState() - could not invert flexibility\n";
00583 
00584 
00585   // set Ki
00586   Ki = new Matrix(crdTransf->getInitialGlobalStiffMatrix(kvInit));
00587 
00588   return *Ki;
00589 }
00590 
00591 const Vector &
00592 NLBeamColumn3d::getResistingForce(void)
00593 {
00594   // Will remove once we clean up the corotational 3d transformation -- MHS
00595   crdTransf->update();
00596 
00597   Vector p0Vec(p0, 5);
00598 
00599   return crdTransf->getGlobalResistingForce(Se, p0Vec);
00600 }
00601 
00602 
00603 void
00604 NLBeamColumn3d::initializeSectionHistoryVariables (void)
00605 {
00606     for (int i = 0; i < nSections; i++)
00607     {
00608         int order = sections[i]->getOrder();
00609         
00610         fs[i] = Matrix(order,order);
00611         vs[i] = Vector(order);
00612         Ssr[i] = Vector(order);
00613         
00614         vscommit[i] = Vector(order);
00615     }
00616 }
00617 
00618 
00619 
00620 int 
00621 NLBeamColumn3d::update(void)
00622 {
00623 
00624   // if have completed a recvSelf() - do a revertToLastCommit
00625   // to get Ssr, etc. set correctly
00626   if (initialFlag == 2)
00627     this->revertToLastCommit();
00628 
00629     // update the transformation
00630     crdTransf->update();
00631        
00632     // get basic displacements and increments
00633     static Vector v(NEBD);
00634     static Vector dv(NEBD);
00635      
00636     v = crdTransf->getBasicTrialDisp();    
00637     dv = crdTransf->getBasicIncrDeltaDisp();    
00638 
00639     // get integration point positions and weights
00640     const Matrix &xi_pt = quadRule.getIntegrPointCoords(nSections);
00641     const Vector &weight = quadRule.getIntegrPointWeights(nSections);
00642      
00643     static Vector vr(NEBD);       // element residual displacements
00644     static Matrix f(NEBD,NEBD);   // element flexibility matrix
00645 
00646     static Matrix I(NEBD,NEBD);   // an identity matrix for matrix inverse
00647     double dW;                    // section strain energy (work) norm 
00648     int i;
00649     
00650     I.Zero();
00651     for (i=0; i<NEBD; i++)
00652       I(i,i) = 1.0;
00653 
00654     // calculate nodal force increments and update nodal forces
00655     static Vector dSe(NEBD);
00656 
00657     // dSe = kv * dv;
00658     dSe.addMatrixVector(0.0, kv, dv, 1.0);
00659 
00660     double L = crdTransf->getInitialLength();
00661     double oneOverL  = 1.0/L;
00662 
00663     for (int j=0; j < maxIters; j++) {
00664       Se += dSe;
00665   
00666       // initialize f and vr for integration
00667       f.Zero();
00668       vr.Zero();
00669 
00670       for (i=0; i<nSections; i++) {
00671         int order      = sections[i]->getOrder();
00672         const ID &code = sections[i]->getType();
00673 
00674         Vector Ss(workArea, order);
00675         Vector dSs(&workArea[order], order);
00676         Vector dvs(&workArea[2*order], order);
00677         
00678         Matrix fb(&workArea[3*order], order, NEBD);
00679         
00680         double xL  = xi_pt(i,0);
00681         double xL1 = xL-1.0;
00682 
00683         // calculate total section forces
00684         // Ss = b*Se + bp*currDistrLoad;
00685         //Ss.addMatrixVector(0.0, b[i], Se, 1.0);
00686         int ii;
00687         for (ii = 0; ii < order; ii++) {
00688           switch(code(ii)) {
00689           case SECTION_RESPONSE_P:
00690             Ss(ii) = Se(0);
00691             break;
00692           case SECTION_RESPONSE_MZ:
00693             Ss(ii) = xL1*Se(1) + xL*Se(2);
00694             break;
00695           case SECTION_RESPONSE_VY:
00696             Ss(ii) = oneOverL*(Se(1)+Se(2));
00697             break;
00698           case SECTION_RESPONSE_MY:
00699             Ss(ii) = xL1*Se(3) + xL*Se(4);
00700             break;
00701           case SECTION_RESPONSE_VZ:
00702             Ss(ii) = oneOverL*(Se(3)+Se(4));
00703             break;
00704           case SECTION_RESPONSE_T:
00705             Ss(ii) = Se(5);
00706             break;
00707           default:
00708             Ss(ii) = 0.0;
00709             break;
00710           }
00711         }
00712 
00713         // Add the effects of element loads, if present
00714         if (sp != 0) {
00715           const Matrix &s_p = *sp;
00716           for (ii = 0; ii < order; ii++) {
00717             switch(code(ii)) {
00718             case SECTION_RESPONSE_P:
00719               Ss(ii) += s_p(0,i);
00720               break;
00721             case SECTION_RESPONSE_MZ:
00722               Ss(ii) += s_p(1,i);
00723               break;
00724             case SECTION_RESPONSE_VY:
00725               Ss(ii) += s_p(2,i);
00726               break;
00727             case SECTION_RESPONSE_MY:
00728               Ss(ii) += s_p(3,i);
00729               break;
00730             case SECTION_RESPONSE_VZ:
00731               Ss(ii) += s_p(4,i);
00732               break;
00733             default:
00734               break;
00735             }
00736           }
00737         }
00738 
00739           dSs = Ss;
00740           dSs.addVector(1.0, Ssr[i], -1.0);  // dSs = Ss - Ssr[i];
00741  
00742           // compute section deformation increments
00743           //       vs += fs * dSs;     
00744           dvs.addMatrixVector(0.0, fs[i], dSs, 1.0);
00745 
00746 
00747           if (initialFlag != 0)
00748             vs[i] += dvs;
00749 
00750           sections[i]->setTrialSectionDeformation(vs[i]);
00751           
00752           // get section resisting forces
00753           Ssr[i] = sections[i]->getStressResultant();
00754 
00755           // get section flexibility matrix
00756           fs[i] = sections[i]->getSectionFlexibility();
00757 
00758           // calculate section residual deformations
00759           // dvs = fs * (Ss - Ssr);
00760           dSs = Ss;
00761           dSs.addVector(1.0, Ssr[i], -1.0);  // dSs = Ss - Ssr[i];
00762 
00763           dvs.addMatrixVector(0.0, fs[i], dSs, 1.0);
00764 
00765           // integrate element flexibility matrix
00766           // f = f + (b^ fs * b) * weight(i);
00767           //f.addMatrixTripleProduct(1.0, b[i], fs[i], weight(i));
00768           int jj;
00769           const Matrix &fSec = fs[i];
00770           fb.Zero();
00771           double tmp;
00772           for (ii = 0; ii < order; ii++) {
00773             switch(code(ii)) {
00774             case SECTION_RESPONSE_P:
00775               for (jj = 0; jj < order; jj++)
00776                 fb(jj,0) += fSec(jj,ii)*weight(i);
00777               break;
00778             case SECTION_RESPONSE_MZ:
00779               for (jj = 0; jj < order; jj++) {
00780                 tmp = fSec(jj,ii)*weight(i);
00781                 fb(jj,1) += xL1*tmp;
00782                 fb(jj,2) += xL*tmp;
00783               }
00784               break;
00785             case SECTION_RESPONSE_VY:
00786               for (jj = 0; jj < order; jj++) {
00787                 tmp = oneOverL*fSec(jj,ii)*weight(i);
00788                 fb(jj,1) += tmp;
00789                 fb(jj,2) += tmp;
00790               }
00791               break;
00792             case SECTION_RESPONSE_MY:
00793               for (jj = 0; jj < order; jj++) {
00794                 tmp = fSec(jj,ii)*weight(i);
00795                 fb(jj,3) += xL1*tmp;
00796                 fb(jj,4) += xL*tmp;
00797               }
00798               break;
00799             case SECTION_RESPONSE_VZ:
00800               for (jj = 0; jj < order; jj++) {
00801                 tmp = oneOverL*fSec(jj,ii)*weight(i);
00802                 fb(jj,3) += tmp;
00803                 fb(jj,4) += tmp;
00804               }
00805               break;
00806             case SECTION_RESPONSE_T:
00807               for (jj = 0; jj < order; jj++)
00808                 fb(jj,5) += fSec(jj,ii)*weight(i);
00809               break;
00810             default:
00811               break;
00812             }
00813           }
00814           for (ii = 0; ii < order; ii++) {
00815             switch (code(ii)) {
00816             case SECTION_RESPONSE_P:
00817               for (jj = 0; jj < 6; jj++)
00818                 f(0,jj) += fb(ii,jj);
00819               break;
00820             case SECTION_RESPONSE_MZ:
00821               for (jj = 0; jj < 6; jj++) {
00822                 tmp = fb(ii,jj);
00823                 f(1,jj) += xL1*tmp;
00824                 f(2,jj) += xL*tmp;
00825               }
00826               break;
00827             case SECTION_RESPONSE_VY:
00828               for (jj = 0; jj < 6; jj++) {
00829                 tmp = oneOverL*fb(ii,jj);
00830                 f(1,jj) += tmp;
00831                 f(2,jj) += tmp;
00832               }
00833               break;
00834             case SECTION_RESPONSE_MY:
00835               for (jj = 0; jj < 6; jj++) {
00836                 tmp = fb(ii,jj);
00837                 f(3,jj) += xL1*tmp;
00838                 f(4,jj) += xL*tmp;
00839               }
00840               break;
00841             case SECTION_RESPONSE_VZ:
00842               for (jj = 0; jj < 6; jj++) {
00843                 tmp = oneOverL*fb(ii,jj);
00844                 f(3,jj) += tmp;
00845                 f(4,jj) += tmp;
00846               }
00847               break;
00848             case SECTION_RESPONSE_T:
00849               for (jj = 0; jj < 6; jj++)
00850                 f(5,jj) += fb(ii,jj);
00851               break;
00852             default:
00853               break;
00854             }
00855           }
00856 
00857           // integrate residual deformations
00858           // vr += (b^ (vs + dvs)) * weight(i);
00859           //vr.addMatrixTransposeVector(1.0, b[i], vs[i] + dvs, weight(i));
00860           dvs.addVector(1.0, vs[i], 1.0);
00861           double dei;
00862           for (ii = 0; ii < order; ii++) {
00863             dei = dvs(ii)*weight(i);
00864             switch(code(ii)) {
00865             case SECTION_RESPONSE_P:
00866               vr(0) += dei; break;
00867             case SECTION_RESPONSE_MZ:
00868               vr(1) += xL1*dei; vr(2) += xL*dei; break;
00869             case SECTION_RESPONSE_VY:
00870               tmp = oneOverL*dei;
00871               vr(1) += tmp; vr(2) += tmp; break;
00872             case SECTION_RESPONSE_MY:
00873               vr(3) += xL1*dei; vr(4) += xL*dei; break;
00874             case SECTION_RESPONSE_VZ:
00875               tmp = oneOverL*dei;
00876               vr(3) += tmp; vr(4) += tmp; break;
00877             case SECTION_RESPONSE_T:
00878               vr(5) += dei; break;
00879             default:
00880               break;
00881             }
00882           }
00883       }  
00884       
00885       f  *= L;
00886       vr *= L;
00887 
00888       if (!isTorsion) {
00889         f(5,5) = DefaultLoverGJ;
00890         vr(5) = Se(5)*DefaultLoverGJ;
00891       }
00892 
00893       // calculate element stiffness matrix
00894       if (f.Invert(kv) < 0)
00895         opserr << "NLBeamColumn3d::updateElementState() - could not invert flexibility\n";
00896 
00897       // dv = v - vr;
00898       dv = v;
00899       dv.addVector(1.0, vr, -1.0);
00900       
00901       // dSe = kv * dv;
00902       dSe.addMatrixVector(0.0, kv, dv, 1.0);
00903 
00904       dW = dv^ dSe;
00905       if (fabs(dW) < tol)
00906         break;
00907 
00908       if (maxIters == 1) {
00909         opserr << "NLBeamColumn3d::updateElementState() - element: " << this->getTag() << " failed to converge but going on\n";
00910         break;
00911       }
00912       if (j == (maxIters-1)) {
00913         opserr << "NLBeamColumn3d::updateElementState() - element: " << this->getTag() << " failed to converge\n";
00914         opserr << "dW: " << dW  << "\n dv: " << dv << " dSe: " << dSe << endln;
00915         return -1;
00916       }
00917     }
00918       
00919     // determine resisting forces
00920     Se += dSe;
00921 
00922     initialFlag = 1;
00923 
00924     return 0;
00925 }
00926 
00927 
00928 
00929 void NLBeamColumn3d::getGlobalDispls(Vector &dg) const
00930 {
00931    // determine global displacements
00932    const Vector &disp1 = theNodes[0]->getTrialDisp();
00933    const Vector &disp2 = theNodes[1]->getTrialDisp();
00934 
00935    for (int i = 0; i < NND; i++)
00936    {
00937       dg(i)     = disp1(i);
00938       dg(i+NND) = disp2(i);
00939    }
00940 }
00941 
00942 
00943 
00944 void NLBeamColumn3d::getGlobalAccels(Vector &ag) const
00945 {
00946    // determine global displacements
00947    const Vector &accel1 = theNodes[0]->getTrialAccel();
00948    const Vector &accel2 = theNodes[1]->getTrialAccel();
00949 
00950    for (int i = 0; i < NND; i++)
00951    {
00952       ag(i)     = accel1(i);
00953       ag(i+NND) = accel2(i);
00954    }
00955 }
00956 
00957 
00958 void NLBeamColumn3d::getForceInterpolatMatrix(double xi, Matrix &b, const ID &code)
00959 {
00960    b.Zero();
00961    double L = crdTransf->getInitialLength();
00962     
00963    for (int i = 0; i < code.Size(); i++)
00964    {
00965       switch (code(i))
00966       {
00967          case SECTION_RESPONSE_MZ:              // Moment, Mz, interpolation
00968             b(i,1) = xi - 1.0;
00969             b(i,2) = xi;
00970             break;
00971          case SECTION_RESPONSE_P:               // Axial, P, interpolation
00972             b(i,0) = 1.0;
00973             break;
00974          case SECTION_RESPONSE_VY:              // Shear, Vy, interpolation
00975             b(i,1) = b(i,2) = 1.0/L;
00976             break;
00977          case SECTION_RESPONSE_MY:              // Moment, My, interpolation
00978             b(i,3) = xi - 1.0;
00979             b(i,4) = xi;
00980             break;
00981          case SECTION_RESPONSE_VZ:              // Shear, Vz, interpolation
00982             b(i,3) = b(i,4) = 1.0/L;
00983             break;
00984          case SECTION_RESPONSE_T:               // Torque, T, interpolation
00985             b(i,5) = 1.0;
00986             break;
00987          default:
00988             break;
00989       } 
00990    }
00991 }
00992 
00993 
00994 void NLBeamColumn3d::getDistrLoadInterpolatMatrix(double xi, Matrix &bp, const ID &code)
00995 {
00996    bp.Zero();
00997    double L = crdTransf->getInitialLength();
00998 
00999    for (int i = 0; i < code.Size(); i++)
01000    {
01001       switch (code(i))
01002       {
01003          case SECTION_RESPONSE_MZ:              // Moment, Mz, interpolation
01004             bp(i,1) = xi*(xi-1)*L*L/2;
01005             break;
01006          case SECTION_RESPONSE_P:               // Axial, P, interpolation
01007             bp(i,0) = (1-xi)*L;
01008             break;
01009          case SECTION_RESPONSE_VY:              // Shear, Vy, interpolation
01010             bp(i,1) = (xi-0.5)*L;
01011             break;
01012          case SECTION_RESPONSE_MY:              // Moment, My, interpolation
01013             bp(i,2) = xi*(1-xi)*L*L/2;
01014             break;
01015          case SECTION_RESPONSE_VZ:              // Shear, Vz, interpolation
01016             bp(i,2) = (0.5-xi)*L;
01017             break;
01018          case SECTION_RESPONSE_T:               // Torsion, T, interpolation
01019             break;
01020          default:
01021             break;
01022       }
01023    }
01024 }
01025 
01026     
01027 const Matrix &
01028 NLBeamColumn3d::getMass(void)
01029 { 
01030   double L = crdTransf->getInitialLength();
01031 
01032   theMatrix(0,0) = theMatrix(1,1) = theMatrix(2,2) =
01033     theMatrix(6,6) = theMatrix(7,7) = theMatrix(8,8) = 0.5*rho*L;
01034   
01035   return theMatrix;
01036 }
01037 
01038 
01039 void 
01040 NLBeamColumn3d::zeroLoad(void)
01041 {
01042   if (sp != 0)
01043     sp->Zero();
01044 
01045   p0[0] = 0.0;
01046   p0[1] = 0.0;
01047   p0[2] = 0.0;
01048   p0[3] = 0.0;
01049   p0[4] = 0.0;
01050 
01051   load.Zero();
01052 }
01053 
01054 int
01055 NLBeamColumn3d::addLoad(ElementalLoad *theLoad, double loadFactor)
01056 {
01057   int type;
01058   const Vector &data = theLoad->getData(type, loadFactor);
01059   
01060   if (sp == 0) {
01061     sp = new Matrix(5,nSections);
01062     if (sp == 0) {
01063       opserr << "NLBeamColumn3d::addLoad -- out of memory\n";
01064       exit(-1);
01065     }
01066   }
01067 
01068   const Matrix &xi_pt = quadRule.getIntegrPointCoords(nSections);
01069   double L = crdTransf->getInitialLength();
01070 
01071   if (type == LOAD_TAG_Beam3dUniformLoad) {
01072     double wy = data(0)*loadFactor;  // Transverse
01073     double wz = data(1)*loadFactor;  // Transverse
01074     double wx = data(2)*loadFactor;  // Axial
01075 
01076     Matrix &s_p = *sp;
01077 
01078     // Accumulate applied section forces due to element loads
01079     for (int i = 0; i < nSections; i++) {
01080       double x = xi_pt(i,0)*L;
01081       // Axial
01082       s_p(0,i) += wx*(L-x);
01083       // Moment
01084       s_p(1,i) += wy*0.5*x*(x-L);
01085       // Shear
01086       s_p(2,i) += wy*(x-0.5*L);
01087       // Moment
01088       s_p(3,i) += wz*0.5*x*(L-x);
01089       // Shear
01090       s_p(4,i) += wz*(x-0.5*L);
01091     }
01092   
01093     // Accumulate reactions in basic system
01094     p0[0] -= wx*L;
01095     double V;
01096     V = 0.5*wy*L;
01097     p0[1] -= V;
01098     p0[2] -= V;
01099     V = 0.5*wz*L;
01100     p0[3] -= V;
01101     p0[4] -= V;
01102   }
01103   else if (type == LOAD_TAG_Beam3dPointLoad) {
01104     double Py = data(0)*loadFactor;
01105     double Pz = data(1)*loadFactor;
01106     double N  = data(2)*loadFactor;
01107     double aOverL = data(3);
01108     double a = aOverL*L;
01109 
01110     double Vy2 = Py*aOverL;
01111     double Vy1 = Py-Vy2;
01112 
01113     double Vz2 = Pz*aOverL;
01114     double Vz1 = Pz-Vz2;
01115 
01116     Matrix &s_p = *sp;
01117 
01118     // Accumulate applied section forces due to element loads
01119     for (int i = 0; i < nSections; i++) {
01120       double x = xi_pt(i,0)*L;
01121       if (x <= a) {
01122         s_p(0,i) += N;
01123         s_p(1,i) -= x*Vy1;
01124         s_p(2,i) -= Vy1;
01125         s_p(3,i) -= x*Vz1;
01126         s_p(4,i) -= Vz1;
01127       }
01128       else {
01129         s_p(1,i) -= (L-x)*Vy2;
01130         s_p(2,i) += Vy2;
01131         s_p(3,i) -= (L-x)*Vz2;
01132         s_p(4,i) += Vz2;
01133       }
01134     }
01135 
01136     // Accumulate reactions in basic system
01137     p0[0] -= N;
01138     p0[1] -= Vy1;
01139     p0[2] -= Vy2;
01140     p0[3] -= Vz1;
01141     p0[4] -= Vz2;
01142   }
01143 
01144   else {
01145     opserr << "NLBeamColumn3d::addLoad()  -- load type unknown for element with tag: " << this->getTag() << endln;
01146     return -1;
01147   }
01148 
01149   return 0;
01150 }
01151 
01152 
01153 int 
01154 NLBeamColumn3d::addInertiaLoadToUnbalance(const Vector &accel)
01155 {
01156   // Check for a quick return
01157   if (rho == 0.0)
01158     return 0;
01159 
01160   // get R * accel from the nodes
01161   const Vector &Raccel1 = theNodes[0]->getRV(accel);
01162   const Vector &Raccel2 = theNodes[1]->getRV(accel);    
01163 
01164   double L = crdTransf->getInitialLength();
01165   double m = 0.5*rho*L;
01166 
01167   load(0) -= m*Raccel1(0);
01168   load(1) -= m*Raccel1(1);
01169   load(2) -= m*Raccel1(2);
01170   load(6) -= m*Raccel2(0);
01171   load(7) -= m*Raccel2(1);
01172   load(8) -= m*Raccel2(2);
01173 
01174   return 0;
01175 }
01176 
01177 
01178 const Vector &
01179 NLBeamColumn3d::getResistingForceIncInertia()
01180 {       
01181   // Check for a quick return
01182   if (rho == 0.0)
01183     theVector = this->getResistingForce();
01184 
01185   if (rho != 0.0) {
01186     const Vector &accel1 = theNodes[0]->getTrialAccel();
01187     const Vector &accel2 = theNodes[1]->getTrialAccel();
01188     
01189     // Compute the current resisting force
01190     theVector = this->getResistingForce();
01191     
01192     double L = crdTransf->getInitialLength();
01193     double m = 0.5*rho*L;
01194     
01195     theVector(0) += m*accel1(0);
01196     theVector(1) += m*accel1(1);
01197     theVector(2) += m*accel1(2);
01198     theVector(6) += m*accel2(0);
01199     theVector(7) += m*accel2(1);
01200     theVector(8) += m*accel2(2);
01201 
01202     // add the damping forces if rayleigh damping
01203     if (alphaM != 0.0 || betaK != 0.0 || betaK0 != 0.0 || betaKc != 0.0)
01204       theVector += this->getRayleighDampingForces();
01205     
01206   } else {
01207 
01208     // add the damping forces if rayleigh damping
01209     if (betaK != 0.0 || betaK0 != 0.0 || betaKc != 0.0)
01210       theVector += this->getRayleighDampingForces();
01211   }
01212 
01213   return theVector;
01214 }
01215 
01216 int
01217 NLBeamColumn3d::sendSelf(int commitTag, Channel &theChannel)
01218 {
01219   // place the integer data into an ID
01220 
01221   int dbTag = this->getDbTag();
01222   int i, j , k;
01223   int loc = 0;
01224   
01225   static ID idData(9);
01226   idData(0) = this->getTag();
01227   idData(1) = connectedExternalNodes(0);
01228   idData(2) = connectedExternalNodes(1);
01229   idData(3) = nSections;
01230   idData(4) = maxIters;
01231   idData(5) = initialFlag;
01232   idData(6) = crdTransf->getClassTag();
01233   int crdTransfDbTag  = crdTransf->getDbTag();
01234   if (crdTransfDbTag  == 0) {
01235       crdTransfDbTag = theChannel.getDbTag();
01236       if (crdTransfDbTag  != 0) {
01237            crdTransf->setDbTag(crdTransfDbTag);
01238        }
01239   }
01240   idData(7) = crdTransfDbTag;
01241   idData(8) = (isTorsion) ? 1 : 0;
01242   
01243   if (theChannel.sendID(dbTag, commitTag, idData) < 0) {
01244      opserr << "NLBeamColumn3d::sendSelf() - %s\n",
01245                              "failed to send ID data";
01246      return -1;
01247   }    
01248   
01249   if (crdTransf->sendSelf(commitTag, theChannel) < 0) {
01250      opserr << "NLBeamColumn3d::sendSelf() - %s\n",
01251                              "failed to send crdTranf";
01252      return -1;
01253   }      
01254   
01255   //
01256   // send an ID for the sections containing each sections dbTag and classTag
01257   // if section ha no dbTag get one and assign it
01258   //
01259 
01260   ID idSections(2*nSections);
01261   loc = 0;
01262   for (i = 0; i<nSections; i++) {
01263     int sectClassTag = sections[i]->getClassTag();
01264     int sectDbTag = sections[i]->getDbTag();
01265     if (sectDbTag == 0) {
01266       sectDbTag = theChannel.getDbTag();
01267       sections[i]->setDbTag(sectDbTag);
01268     }
01269 
01270     idSections(loc) = sectClassTag;
01271     idSections(loc+1) = sectDbTag;
01272     loc += 2;
01273   }
01274 
01275   if (theChannel.sendID(dbTag, commitTag, idSections) < 0)  {
01276     opserr << "NLBeamColumn3d::sendSelf() - %s\n",
01277                             "failed to send ID data";
01278     return -1;
01279   }    
01280 
01281   //
01282   // send the sections
01283   //
01284   
01285   for (j = 0; j<nSections; j++) {
01286     if (sections[j]->sendSelf(commitTag, theChannel) < 0) {
01287       opserr << "NLBeamColumn3d::sendSelf() - section " << 
01288         j << "failed to send itself\n";
01289       return -1;
01290     }
01291   }
01292   
01293   // into a vector place distrLoadCommit, rho, UeCommit, Secommit and kvcommit
01294   int secDefSize = 0;
01295   for (i = 0; i < nSections; i++) {
01296      int size = sections[i]->getOrder();
01297      secDefSize   += size;
01298   }
01299     
01300   Vector dData(2+NEBD+NEBD*NEBD+secDefSize); 
01301   loc = 0;
01302 
01303   // place double variables into Vector
01304   dData(loc++) = rho;
01305   dData(loc++) = tol;
01306   
01307   // place kvcommit into vector
01308   for (i=0; i<NEBD; i++) 
01309     dData(loc++) = Secommit(i);
01310 
01311   // place kvcommit into vector
01312   for (i=0; i<NEBD; i++) 
01313      for (j=0; j<NEBD; j++)
01314         dData(loc++) = kvcommit(i,j);
01315   
01316   // place vscommit into vector
01317   for (k=0; k<nSections; k++)
01318      for (i=0; i<sections[k]->getOrder(); i++)
01319         dData(loc++) = (vscommit[k])(i);
01320   
01321   if (theChannel.sendVector(dbTag, commitTag, dData) < 0) {
01322      opserr << "NLBeamColumn3d::sendSelf() - %s\n",
01323                              "failed to send Vector data";
01324      return -1;
01325   }    
01326 
01327   return 0;
01328 }
01329 
01330 
01331 int
01332 NLBeamColumn3d::recvSelf(int commitTag, Channel &theChannel, FEM_ObjectBroker &theBroker)
01333 {
01334   //
01335   // into an ID of size 9 place the integer data
01336   //
01337   int dbTag = this->getDbTag();
01338   int i,j,k;
01339 
01340   static ID idData(9);
01341 
01342   if (theChannel.recvID(dbTag, commitTag, idData) < 0)  {
01343     opserr << "NLBeamColumn3d::recvSelf() - %s\n",
01344                             "failed to recv ID data";
01345     return -1;
01346   }    
01347 
01348   this->setTag(idData(0));
01349   connectedExternalNodes(0) = idData(1);
01350   connectedExternalNodes(1) = idData(2);
01351   maxIters = idData(4);
01352   initialFlag = idData(5);
01353   isTorsion = (idData(8) == 1) ? true : false;
01354   
01355   int crdTransfClassTag = idData(6);
01356   int crdTransfDbTag = idData(7);
01357 
01358   // create a new crdTransf object if one needed
01359   if (crdTransf == 0 || crdTransf->getClassTag() != crdTransfClassTag) {
01360       if (crdTransf != 0)
01361           delete crdTransf;
01362       crdTransf = theBroker.getNewCrdTransf3d(crdTransfClassTag);
01363       if (crdTransf == 0) {
01364         opserr << "NLBeamColumn3d::recvSelf() - failed to obtain a CrdTrans object with classTag" <<
01365           crdTransfClassTag << endln;
01366         return -2;        
01367       }
01368   }
01369   crdTransf->setDbTag(crdTransfDbTag);
01370 
01371   // invoke recvSelf on the crdTransf obkject
01372   if (crdTransf->recvSelf(commitTag, theChannel, theBroker) < 0) {
01373     opserr << "NLBeamColumn3d::sendSelf() - failed to recv crdTranf\n";
01374                              
01375      return -3;
01376   }      
01377   
01378   //
01379   // recv an ID for the sections containing each sections dbTag and classTag
01380   //
01381 
01382   ID idSections(2*idData(3));
01383   int loc = 0;
01384 
01385   if (theChannel.recvID(dbTag, commitTag, idSections) < 0)  {
01386     opserr << "NLBeamColumn3d::recvSelf() - %s\n",
01387                             "failed to recv ID data";
01388     return -1;
01389   }    
01390 
01391   //
01392   // now receive the sections
01393   //
01394   if (nSections != idData(3)) {
01395 
01396     //
01397     // we do not have correct number of sections, must delete the old and create
01398     // new ones before can recvSelf on the sections
01399     //
01400 
01401     // delete the old
01402     if (nSections != 0) {
01403       for (int i=0; i<nSections; i++)
01404         delete sections[i];
01405       delete [] sections;
01406     }
01407 
01408     // create a new array to hold pointers
01409     sections = new SectionForceDeformation *[idData(3)];
01410     if (sections == 0) {
01411       opserr << "NLBeamColumn3d::recvSelf() - out of memory creating sections array of size" << idData(3) << endln;
01412       exit(-1);
01413     }    
01414 
01415     // create all those matrices and vectors
01416     nSections = idData(3);
01417     loc = 0;
01418 
01419     // Delete the old
01420     if (vscommit != 0)
01421       delete [] vscommit;
01422   
01423     // Allocate the right number
01424     vscommit = new Vector[nSections];
01425     if (vscommit == 0) {
01426       opserr << "%s -- failed to allocate vscommit array",
01427                               "NLBeamColumn3d::recvSelf";
01428       return -1;
01429     }
01430   
01431     // Delete the old
01432     if (fs != 0)
01433      delete [] fs;
01434     
01435     // Allocate the right number
01436     fs  = new Matrix[nSections];  
01437     if (fs == 0) {
01438      opserr << "%s -- failed to allocate fs array",
01439                              "NLBeamColumn3d::recvSelf";
01440      return -1;
01441     } 
01442     
01443     // Delete the old
01444     if (vs != 0)
01445       delete [] vs;
01446     
01447     // Allocate the right number
01448     vs = new Vector[nSections];  
01449     if (vs == 0) {
01450       opserr << "%s -- failed to allocate vs array",
01451                               "NLBeamColumn3d::recvSelf";
01452       return -1;
01453     }
01454    
01455     // Delete the old
01456     if (Ssr != 0)
01457       delete [] Ssr;
01458     
01459     // Allocate the right number
01460     Ssr = new Vector[nSections];  
01461     if (Ssr == 0) {
01462       opserr << "%s -- failed to allocate Ssr array",
01463                               "NLBeamColumn3d::recvSelf";
01464       return -1;
01465     }
01466     
01467     for (i=0; i<nSections; i++) {
01468       int sectClassTag = idSections(loc);
01469       int sectDbTag = idSections(loc+1);
01470       loc += 2;
01471       sections[i] = theBroker.getNewSection(sectClassTag);
01472       if (sections[i] == 0) {
01473         opserr << "NLBeamColumn3d::recvSelf() - " << 
01474           "Broker could not create Section of class type " << sectClassTag << endln;
01475         return -1;
01476       }
01477 
01478       sections[i]->setDbTag(sectDbTag);
01479       if (sections[i]->recvSelf(commitTag, theChannel, theBroker) < 0) {
01480         opserr << "NLBeamColumn3d::recvSelf() - section " <<
01481           i << "failed to recv itself\n";
01482         return -1;
01483       }     
01484     }
01485 
01486     // Set up section history variables 
01487     this->initializeSectionHistoryVariables();
01488 
01489   } else {
01490 
01491     // 
01492     // for each existing section, check it is of correct type
01493     // (if not delete old & create a new one) then recvSelf on it
01494     //
01495     
01496     loc = 0;
01497     for (i=0; i<nSections; i++) {
01498       int sectClassTag = idSections(loc);
01499       int sectDbTag = idSections(loc+1);
01500       loc += 2;
01501 
01502       // check of correct type
01503       if (sections[i]->getClassTag() !=  sectClassTag) {
01504         // delete the old section[i] and create a new one
01505         delete sections[i];
01506         sections[i] = theBroker.getNewSection(sectClassTag);
01507         if (sections[i] == 0) {
01508           opserr << "NLBeamColumn3d::recvSelf() - " <<
01509             "Broker could not create Section of class type" << sectClassTag << endln;
01510           exit(-1);
01511         }
01512       }
01513 
01514       // recvvSelf on it
01515       sections[i]->setDbTag(sectDbTag);
01516       if (sections[i]->recvSelf(commitTag, theChannel, theBroker) < 0) {
01517         opserr << "NLBeamColumn3d::recvSelf() - section " << 
01518           i << "failed to recv itself\n";
01519         return -1;
01520       }     
01521     }
01522   }
01523   
01524   // into a vector place distrLoadCommit, rho, UeCommit, Secommit and kvcommit
01525   int secDefSize = 0;
01526   for (int ii = 0; ii < nSections; ii++)
01527   {
01528      int size = sections[ii]->getOrder();
01529      secDefSize   += size;
01530   }
01531 
01532   Vector dData(2+NEBD+NEBD*NEBD+secDefSize);   
01533   
01534   if (theChannel.recvVector(dbTag, commitTag, dData) < 0)  {
01535     opserr << "NLBeamColumn3d::sendSelf() - failed to recv Vector data\n";
01536     return -1;
01537   }    
01538   
01539   loc = 0;
01540   
01541   // place double variables into Vector
01542   rho = dData(loc++);
01543   tol = dData(loc++);
01544   
01545   // place kvcommit into vector
01546   for (i=0; i<NEBD; i++) 
01547     Secommit(i) = dData(loc++);
01548   
01549   // place kvcommit into vector
01550   for (i=0; i<NEBD; i++) 
01551     for (j=0; j<NEBD; j++)
01552         kvcommit(i,j) = dData(loc++);
01553   
01554   kv   = kvcommit;
01555   Se   = Secommit;
01556 
01557   for (k = 0; k < nSections; k++) {
01558     int order = sections[k]->getOrder();
01559     
01560     // place vscommit into vector
01561     vscommit[k] = Vector(order);
01562     for (i = 0; i < order; i++)
01563       (vscommit[k])(i) = dData(loc++);
01564   }
01565 
01566   initialFlag = 2;  
01567 
01568   return 0;
01569 }
01570 
01571 
01572 void 
01573 NLBeamColumn3d::compSectionDisplacements(Vector sectionCoords[], Vector sectionDispls[]) const
01574 {
01575    // update the transformation
01576    crdTransf->update();
01577        
01578    // get basic displacements and increments
01579    static Vector ub(NEBD);
01580    ub = crdTransf->getBasicTrialDisp();    
01581   
01582    // get integration point positions and weights
01583    const Matrix &xi_pt  = quadRule.getIntegrPointCoords(nSections);
01584 
01585    // setup Vandermode and CBDI influence matrices
01586    int i;
01587    double xi;
01588  
01589    // get CBDI influence matrix
01590    Matrix ls(nSections, nSections);
01591    double L = crdTransf->getInitialLength();
01592    getCBDIinfluenceMatrix(nSections, xi_pt, L, ls);
01593      
01594    // get section curvatures
01595    Vector kappa_y(nSections);  // curvature
01596    Vector kappa_z(nSections);  // curvature
01597    static Vector vs;                // section deformations 
01598         
01599    for (i=0; i<nSections; i++) {
01600        // THIS IS VERY INEFFICIENT ... CAN CHANGE IF RUNS TOO SLOW
01601        int sectionKey1 = 0;
01602        int sectionKey2 = 0;
01603        const ID &code = sections[i]->getType();
01604        int j;
01605        for (j = 0; j < code.Size(); j++)
01606        {
01607            if (code(j) == SECTION_RESPONSE_MZ)
01608                sectionKey1 = j;
01609            if (code(j) == SECTION_RESPONSE_MY)
01610                sectionKey2 = j;
01611        }
01612        if (sectionKey1 == 0) {
01613          opserr << "FATAL NLBeamColumn3d::compSectionResponse - section does not provide Mz response\n";
01614          exit(-1);
01615        }
01616        if (sectionKey2 == 0) {
01617          opserr << "FATAL NLBeamColumn3d::compSectionResponse - section does not provide My response\n";
01618          exit(-1);
01619        }
01620        
01621        // get section deformations
01622        vs = sections[i]->getSectionDeformation();
01623        
01624        kappa_z(i) = vs(sectionKey1);
01625        kappa_y(i) = vs(sectionKey2); 
01626    }
01627 
01628    //cout << "kappa_y: " << kappa_y;   
01629    //cout << "kappa_z: " << kappa_z;   
01630    
01631    Vector v(nSections), w(nSections);
01632    static Vector xl(NDM), uxb(NDM);
01633    static Vector xg(NDM), uxg(NDM); 
01634    // double theta;                             // angle of twist of the sections
01635 
01636    // v = ls * kappa_z;  
01637    v.addMatrixVector (0.0, ls, kappa_z, 1.0);  
01638    // w = ls * kappa_y *  (-1);  
01639    w.addMatrixVector (0.0, ls, kappa_y, -1.0);
01640    
01641    for (i=0; i<nSections; i++)
01642    {
01643       xi = xi_pt(i,0);
01644 
01645       xl(0) = xi * L;
01646       xl(1) = 0;
01647       xl(2) = 0;
01648 
01649       // get section global coordinates
01650       sectionCoords[i] = crdTransf->getPointGlobalCoordFromLocal(xl);
01651 
01652       // compute section displacements
01653       //theta  = xi * ub(5); // consider linear variation for angle of twist. CHANGE LATER!!!!!!!!!!
01654       uxb(0) = xi * ub(0); // consider linear variation for axial displacement. CHANGE LATER!!!!!!!!!!
01655       uxb(1) = v(i);
01656       uxb(2) = w(i);
01657           
01658       // get section displacements in global system 
01659       sectionDispls[i] = crdTransf->getPointGlobalDisplFromBasic(xi, uxb);
01660    }           
01661 }
01662 
01663 
01664 void
01665 NLBeamColumn3d::Print(OPS_Stream &s, int flag)
01666 {
01667 
01668   // flags with negative values are used by GSA
01669    if (flag == -1) { 
01670     int eleTag = this->getTag();
01671     s << "NL_BEAM\t" << eleTag << "\t";
01672     s << sections[0]->getTag() << "\t" << sections[nSections-1]->getTag(); 
01673     s  << "\t" << connectedExternalNodes(0) << "\t" << connectedExternalNodes(1);
01674     s << "\t0\t0.0000000\n";
01675    }  
01676 
01677    else if (flag < -1) {
01678       int eleTag = this->getTag();
01679       int counter = (flag +1) * -1;
01680       int i;
01681       const Vector &force = this->getResistingForce();
01682       s << "FORCE\t" << eleTag << "\t" << counter << "\t0";
01683       for (i=0; i<3; i++)
01684         s << "\t" << force(i);
01685       s << endln;
01686       s << "FORCE\t" << eleTag << "\t" << counter << "\t1";
01687       for (i=0; i<3; i++)
01688         s << "\t" << force(i+6);
01689       s << endln;
01690       s << "MOMENT\t" << eleTag << "\t" << counter << "\t0";
01691       for (i=3; i<6; i++)
01692         s << "\t" << force(i);
01693       s << endln;
01694       s << "MOMENT\t" << eleTag << "\t" << counter << "\t1";
01695       for (i=3; i<6; i++)
01696         s << "\t" << force(i+6);
01697       s << endln;
01698    }
01699    
01700    else if (flag == 1) {
01701      static Vector xAxis(3);
01702      static Vector yAxis(3);
01703      static Vector zAxis(3);
01704      
01705      crdTransf->getLocalAxes(xAxis, yAxis, zAxis);
01706                         
01707      s << "#NLBeamColumn3D\n";
01708      s << "#LocalAxis " << xAxis(0) << " " << xAxis(1) << " " << xAxis(2) 
01709        << " " << zAxis(0) << " " << zAxis(1) << " " << zAxis(2) << endln;
01710 
01711      const Vector &node1Crd = theNodes[0]->getCrds();
01712      const Vector &node2Crd = theNodes[1]->getCrds();   
01713      const Vector &node1Disp = theNodes[0]->getDisp();
01714      const Vector &node2Disp = theNodes[1]->getDisp();    
01715      
01716      s << "#NODE " << node1Crd(0) << " " << node1Crd(1) << " " << node1Crd(2)
01717        << " " << node1Disp(0) << " " << node1Disp(1) << " " << node1Disp(2)
01718        << " " << node1Disp(3) << " " << node1Disp(4) << " " << node1Disp(5) << endln;
01719      
01720      s << "#NODE " << node2Crd(0) << " " << node2Crd(1) << " " << node2Crd(2)
01721        << " " << node2Disp(0) << " " << node2Disp(1) << " " << node2Disp(2)
01722        << " " << node2Disp(3) << " " << node2Disp(4) << " " << node2Disp(5) << endln;
01723 
01724      // allocate array of vectors to store section coordinates and displacements
01725      static int maxNumSections = 0;
01726      static Vector *coords = 0;
01727      static Vector *displs = 0;
01728      if (maxNumSections < nSections) {
01729        if (coords != 0) 
01730          delete [] coords;
01731        if (displs != 0)
01732          delete [] displs;
01733        
01734        coords = new Vector [nSections];
01735        displs = new Vector [nSections];
01736        
01737        if (!coords) {
01738          opserr << "NLBeamColumn3d::Print() -- failed to allocate coords array";   
01739          exit(-1);
01740        }
01741        
01742        int i;
01743        for (i = 0; i < nSections; i++)
01744          coords[i] = Vector(NDM);
01745        
01746        if (!displs) {
01747          opserr << "NLBeamColumn3d::Print() -- failed to allocate coords array";   
01748          exit(-1);
01749        }
01750        
01751        for (i = 0; i < nSections; i++)
01752          displs[i] = Vector(NDM);
01753        
01754        maxNumSections = nSections;
01755      }
01756      
01757      // compute section location & displacements
01758      this->compSectionDisplacements(coords, displs);
01759      
01760      // spit out the section location & invoke print on the scetion
01761      for (int i=0; i<nSections; i++) {
01762        s << "#SECTION " << (coords[i])(0) << " " << (coords[i])(1) << " " << (coords[i])(2);       s << " " << (displs[i])(0) << " " << (displs[i])(1) << " " << (displs[i])(2) << endln;
01763        sections[i]->Print(s, flag); 
01764      }
01765    }
01766    
01767    else {
01768       s << "\nElement: " << this->getTag() << " Type: NLBeamColumn3d ";
01769       s << "\tConnected Nodes: " << connectedExternalNodes ;
01770       s << "\tNumber of Sections: " << nSections << endln;
01771       s << "\tElement End Forces (P MZ1 MZ2 MY1 MY2 T): " << Secommit;
01772       s << "\tResisting Force: " << this->getResistingForce();
01773    }
01774 }
01775 
01776 
01777 OPS_Stream &operator<<(OPS_Stream &s, NLBeamColumn3d &E)
01778 {
01779     E.Print(s);
01780     return s;
01781 }
01782 
01783 int
01784 NLBeamColumn3d::displaySelf(Renderer &theViewer, int displayMode, float fact)
01785 {
01786    
01787   if (displayMode == 1) {
01788 
01789     // first determine the two end points of the element based on
01790     //  the display factor (a measure of the distorted image)
01791     static Vector v1(NDM), v2(NDM);
01792     
01793     const Vector &node1Crd = theNodes[0]->getCrds();
01794     const Vector &node2Crd = theNodes[1]->getCrds();    
01795     const Vector &node1Disp = theNodes[0]->getDisp();
01796     const Vector &node2Disp = theNodes[1]->getDisp();    
01797     
01798     int i;
01799     
01800     // allocate array of vectors to store section coordinates and displacements
01801     static int maxNumSections = 0;
01802     static Vector *coords = 0;
01803     static Vector *displs = 0;
01804     if (maxNumSections < nSections) {
01805       if (coords != 0) 
01806         delete [] coords;
01807       if (displs != 0)
01808         delete [] displs;
01809       
01810       coords = new Vector [nSections];
01811       displs = new Vector [nSections];
01812       
01813       if (!coords) {
01814         opserr << "NLBeamColumn3d::displaySelf() -- failed to allocate coords array";   
01815         exit(-1);
01816       }
01817       
01818       for (i = 0; i < nSections; i++)
01819         coords[i] = Vector(NDM);
01820       
01821       if (!displs) {
01822         opserr << "NLBeamColumn3d::displaySelf() -- failed to allocate coords array";   
01823         exit(-1);
01824       }
01825       
01826       for (i = 0; i < nSections; i++)
01827         displs[i] = Vector(NDM);
01828       
01829       maxNumSections = nSections;
01830     }
01831        
01832     // compute section location & displacements
01833     int error;
01834     this->compSectionDisplacements(coords, displs);
01835 
01836     // get global displacements and coordinates of each section          
01837     
01838     v1 = node1Crd + node1Disp*fact;
01839     
01840     // get global displacements and coordinates of each section          
01841     
01842     for (i = 0; i<nSections; i++) {
01843       v2 = coords[i] + displs[i]*fact;
01844       
01845          error = theViewer.drawLine(v1, v2, 1.0, 1.0);
01846          
01847          if (error)
01848            return error;
01849          v1 = v2;
01850          
01851     }  
01852     
01853     v2 = node2Crd + node2Disp*fact;
01854     
01855     error = theViewer.drawLine(v1, v2, 1.0, 1.0);
01856     
01857     if (error)
01858       return error;
01859   }
01860   return 0;
01861 }
01862 
01863 Response* 
01864 NLBeamColumn3d::setResponse(const char **argv, int argc, Information &eleInformation)
01865 {
01866     //
01867     // we compare argv[0] for known response types 
01868     //
01869 
01870     // global force - 
01871     if (strcmp(argv[0],"forces") == 0 || strcmp(argv[0],"force") == 0
01872         || strcmp(argv[0],"globalForce") == 0 || strcmp(argv[0],"globalForces") == 0)
01873                 return new ElementResponse(this, 1, theVector);
01874 
01875     // local force -
01876     else if (strcmp(argv[0],"localForce") == 0 || strcmp(argv[0],"localForces") == 0)
01877                 return new ElementResponse(this, 2, theVector);
01878 
01879     else if ((strcmp(argv[0],"defoANDforce") == 0) ||
01880              (strcmp(argv[0],"deformationANDforce") == 0) ||
01881              (strcmp(argv[0],"deformationsANDforces") == 0))
01882       return new ElementResponse(this, 4, Vector(24));
01883 
01884     // section response -
01885     else if (strcmp(argv[0],"section") ==0) {
01886       if (argc <= 2)
01887         return 0;
01888         
01889       int sectionNum = atoi(argv[1]);
01890       if (sectionNum > 0 && sectionNum <= nSections)
01891         return sections[sectionNum-1]->setResponse(&argv[2], argc-2, eleInformation);
01892       else
01893         return 0;
01894     }
01895     
01896     else
01897       return 0;
01898 }
01899 
01900 int 
01901 NLBeamColumn3d::getResponse(int responseID, Information &eleInfo)
01902 {
01903   static Vector force(12);
01904   static Vector defoAndForce(24);
01905   double V, N, T, M1, M2;
01906   int i;
01907   double L = crdTransf->getInitialLength();
01908   
01909   switch (responseID) {      
01910   case 1:  // forces
01911     return eleInfo.setVector(this->getResistingForce());
01912     
01913     
01914   case 4:
01915     this->getGlobalDispls(force);
01916     this->getResistingForce();
01917     for (i = 0; i < 12; i++) {
01918       defoAndForce(i) = force(i);
01919       defoAndForce(i+12) = theVector(i);
01920     }
01921     return eleInfo.setVector(defoAndForce);
01922     
01923   case 2:
01924     // Axial
01925     N = Se(0);
01926     force(6) =  N;
01927     force(0) = -N+p0[0];
01928     
01929     // Torsion
01930     T = Se(5);
01931     force(9) =  T;
01932     force(3) = -T;
01933     
01934     // Moments about z and shears along y
01935     M1 = Se(1);
01936     M2 = Se(2);
01937     force(5)  = M1;
01938     force(11) = M2;
01939     V = (M1+M2)/L;
01940     force(1) =  V+p0[1];
01941     force(7) = -V+p0[2];
01942     
01943     // Moments about y and shears along z
01944     M1 = Se(3);
01945     M2 = Se(4);
01946     force(4)  = M1;
01947     force(10) = M2;
01948     V = -(M1+M2)/L;
01949     force(2) = -V+p0[3];
01950     force(8) =  V+p0[4];
01951       
01952     return eleInfo.setVector(force);
01953     
01954   default: 
01955     return -1;
01956   }
01957 }
01958 
01959 int
01960 NLBeamColumn3d::setParameter (const char **argv, int argc, Information &info)
01961 {
01962         int ok = -1;
01963 
01964         // If the parameter belongs to the element itself
01965         if (strcmp(argv[0],"rho") == 0) {
01966                 info.theType = DoubleType;
01967                 return 1;
01968         }
01969 
01970         // If the parameter is belonging to a section or lower
01971         if (strcmp(argv[0],"section") == 0) {
01972 
01973           // For now, no parameters of the section itself:
01974           if (argc<5) {
01975             opserr << "For now: cannot handle parameters of the section itself." << endln;
01976             return -1;
01977           }
01978 
01979           // Reveal section and material tag numbers
01980           int paramSectionTag = atoi(argv[1]);
01981           int paramMatTag     = atoi(argv[3]);
01982 
01983           // Store section and material tag in theInfo
01984           ID *theID = new ID(2);
01985           (*theID)(0) = paramSectionTag;
01986           (*theID)(1) = paramMatTag;
01987           info.theID = theID;
01988           
01989           // Find the right section and call its setParameter method
01990           for (int i=0; i<nSections; i++) {
01991             if (paramSectionTag == sections[i]->getTag()) {
01992               ok = sections[i]->setParameter(&argv[2], argc-2, info);
01993             }
01994           }
01995           
01996           if (ok < 0) {
01997             opserr << "NLBeamColumn2d::setParameter() - could not set parameter. " << endln;
01998             return -1;
01999           }
02000           else {
02001             return ok + 100;
02002           }
02003         }
02004         
02005         // otherwise parameter is unknown for the NLBeamColumn2d class
02006         else
02007           return -1;
02008 }
02009 
02010 int
02011 NLBeamColumn3d::updateParameter (int parameterID, Information &info)
02012 {
02013         ID *paramIDPtr;
02014         int ok = -1;
02015 
02016         switch (parameterID) {
02017         case 1:
02018                 this->rho = info.theDouble;
02019                 return 0;
02020         default:
02021                 if (parameterID >= 100) {
02022                         paramIDPtr = info.theID;
02023                         ID paramID = (*paramIDPtr);
02024                         int paramSectionTag = paramID(0);
02025                         for (int i=0; i<nSections; i++) {
02026                                 if (paramSectionTag == sections[i]->getTag()) {
02027                                         ok = sections[i]->updateParameter(parameterID-100, info);
02028                                 }
02029                         }
02030                         if (ok < 0) {
02031                                 opserr << "NLBeamColumn2d::updateParameter() - could not update parameter. " << endln;
02032                                 return ok;
02033                         }
02034                         else {
02035                                 return ok;
02036                         }
02037                 }
02038                 else
02039                         return -1;
02040         }       
02041 }

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