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

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