Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

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.11 $
00022 // $Date: 2001/07/12 21:54:56 $
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 #include <iomanip.h>
00050 
00051 #include <Information.h>
00052 #include <NLBeamColumn2d.h>
00053 #include <MatrixUtil.h>
00054 #include <GaussQuadRule1d01.h>
00055 #include <GaussLobattoQuadRule1d01.h>
00056 #include <Domain.h>
00057 #include <Channel.h>
00058 #include <FEM_ObjectBroker.h>
00059 #include <Renderer.h>
00060 #include <math.h>
00061 #include <G3Globals.h>
00062 #include <ElementResponse.h>
00063 
00064 #define  NDM   2         // dimension of the problem (2d)
00065 #define  NL    2         // size of uniform load vector
00066 #define  NND   3         // number of nodal dof's
00067 #define  NEGD  6         // number of element global dof's
00068 #define  NEBD  3         // number of element dof's in the basic system
00069 
00070 
00071 // constructor:
00072 // invoked by a FEM_ObjectBroker, recvSelf() needs to be invoked on this object.
00073 NLBeamColumn2d::NLBeamColumn2d(): 
00074 
00075 Element(0,ELE_TAG_NLBeamColumn2d), connectedExternalNodes(2), 
00076 nSections(0), sections(0), crdTransf(0), node1Ptr(0), node2Ptr(0),
00077 rho(0), maxIters(0), tol(0), initialFlag(0), prevDistrLoad(NL),
00078 K(NEGD,NEGD), m(NEGD,NEGD), d(NEGD,NEGD), P(NEGD), Pinert(NEGD), load(NEGD), 
00079 Uepr(NEGD), kv(NEBD,NEBD), Se(NEBD),
00080 distrLoadcommit(NL), Uecommit(NEGD), kvcommit(NEBD,NEBD), Secommit(NEBD), b(0), bp(0),
00081 fs(0), vs(0), Ssr(0), vscommit(0)
00082 {
00083 }
00084 
00085 
00086 // constructor which takes the unique element tag, sections,
00087 // and the node ID's of it's nodal end points. 
00088 // allocates the necessary space needed by each object
00089 NLBeamColumn2d::NLBeamColumn2d (int tag, int nodeI, int nodeJ,
00090                                 int numSections, SectionForceDeformation *sectionPtrs[],
00091                                 CrdTransf2d &coordTransf, double massDensPerUnitLength,
00092     int maxNumIters, double tolerance):
00093 
00094 Element(tag,ELE_TAG_NLBeamColumn2d), connectedExternalNodes(NL),
00095 nSections(numSections), sections(sectionPtrs),
00096 rho(massDensPerUnitLength),maxIters(maxNumIters), tol(tolerance), 
00097 initialFlag(0), prevDistrLoad(NL),
00098 K(NEGD,NEGD), m(NEGD,NEGD), d(NEGD,NEGD), P(NEGD), Pinert(NEGD), load(NEGD), 
00099 Uepr(NEGD), kv(NEBD,NEBD), Se(NEBD), 
00100 distrLoadcommit(NL), Uecommit(NEGD), kvcommit(NEBD,NEBD), Secommit(NEBD), b(0), bp(0) ,
00101 fs(0), vs(0),Ssr(0), vscommit(0)
00102 {
00103    connectedExternalNodes(0) = nodeI;
00104    connectedExternalNodes(1) = nodeJ;    
00105 
00106    // get copy of the sections
00107    
00108    if (!sectionPtrs)
00109    {
00110        cerr << "Error: NLBeamColumn2d::NLBeamColumn2d:  invalid section pointer ";
00111        exit(-1);
00112    }   
00113    
00114    sections = new SectionForceDeformation *[nSections];
00115    if (!sections)
00116    {
00117        cerr << "Error: NLBeamColumn2d::NLBeamColumn2d: could not alocate section pointer";
00118        exit(-1);
00119    }  
00120    
00121    for (int i = 0; i < nSections; i++)
00122    {
00123       if (!sectionPtrs[i])
00124       {
00125    cerr << "Error: NLBeamColumn2d::NLBeamColumn2d: section pointer " << i << endl;
00126           exit(-1);
00127       }  
00128        
00129       sections[i] = sectionPtrs[i]->getCopy();
00130       if (!sections[i])
00131       {
00132    cerr << "Error: NLBeamColumn2d::NLBeamColumn2d: could not create copy of section " << i << endl;
00133           exit(-1);
00134       }
00135    }
00136 
00137    // get copy of the transformation object   
00138    
00139    crdTransf = coordTransf.getCopy(); 
00140    if (!crdTransf)
00141    {
00142       cerr << "Error: NLBeamColumn2d::NLBeamColumn2d: could not create copy of coordinate transformation object" << endl;
00143       exit(-1);
00144    }
00145 
00146    // alocate force interpolation matrices
00147      
00148    b  = new Matrix [nSections];
00149    if (!b)
00150    {
00151        cerr << "NLBeamColumn2d::NLBeamColumn2d() -- failed to allocate b array";
00152        exit(-1);
00153    }
00154    
00155    bp = new Matrix [nSections];
00156    if (!bp)
00157    {
00158        cerr << "NLBeamColumn2d::NLBeamColumn2d() -- failed to allocate bp array";
00159        exit(-1);
00160    }
00161 
00162    // alocate section flexibility matrices and section deformation vectors
00163    fs  = new Matrix [nSections];
00164    if (!fs)
00165    {
00166        cerr << "NLBeamColumn2d::NLBeamColumn2d() -- failed to allocate fs array";
00167        exit(-1);
00168    }
00169    
00170    vs = new Vector [nSections];
00171    if (!vs)
00172    {
00173        cerr << "NLBeamColumn2d::NLBeamColumn2d() -- failed to allocate vs array";
00174        exit(-1);
00175    }
00176 
00177    Ssr  = new Vector [nSections];
00178    if (!Ssr)
00179    {
00180        cerr << "NLBeamColumn2d::NLBeamColumn2d() -- failed to allocate Ssr array";
00181        exit(-1);
00182    }
00183    
00184    vscommit = new Vector [nSections];
00185    if (!vscommit)
00186    {
00187        cerr << "NLBeamColumn2d::NLBeamColumn2d() -- failed to allocate vscommit array";   
00188        exit(-1);
00189    }
00190 }
00191 
00192 
00193 
00194 // ~NLBeamColumn2d():
00195 //  destructor
00196 //      delete must be invoked on any objects created by the object
00197 NLBeamColumn2d::~NLBeamColumn2d()
00198 {
00199    int i;
00200    
00201    if (sections) {
00202       for (i=0; i < nSections; i++)
00203          if (sections[i])
00204             delete sections[i];
00205       delete [] sections;
00206    }
00207 
00208    if (b)
00209      delete [] b;
00210 
00211    if (bp)
00212      delete [] bp;
00213 
00214    if (fs) 
00215      delete [] fs;
00216 
00217    if (vs) 
00218      delete [] vs;
00219 
00220    if (Ssr) 
00221      delete [] Ssr;
00222 
00223    if (vscommit) 
00224      delete [] vscommit;
00225 
00226    if (crdTransf)
00227      delete crdTransf;   
00228 }
00229 
00230 
00231 int
00232 NLBeamColumn2d::getNumExternalNodes(void) const
00233 {
00234    return connectedExternalNodes.Size();
00235 }
00236 
00237 
00238 const ID &
00239 NLBeamColumn2d::getExternalNodes(void) 
00240 {
00241    return connectedExternalNodes;
00242 }
00243 
00244 
00245 int
00246 NLBeamColumn2d::getNumDOF(void) 
00247 {
00248    return NEGD;
00249 }
00250 
00251 
00252 
00253 void
00254 NLBeamColumn2d::setDomain(Domain *theDomain)
00255 {
00256    // check Domain is not null - invoked when object removed from a domain
00257    if (theDomain == 0)
00258    {
00259       node1Ptr = 0;
00260       node2Ptr = 0;
00261         
00262       cerr << "NLBeamColumn2d::setDomain:  theDomain = 0 ";
00263       exit(0); 
00264    }
00265 
00266    // get pointers to the nodes
00267    
00268    int Nd1 = connectedExternalNodes(0);  
00269    int Nd2 = connectedExternalNodes(1);
00270    
00271    node1Ptr = theDomain->getNode(Nd1);
00272    node2Ptr = theDomain->getNode(Nd2);  
00273 
00274    if (node1Ptr == 0)
00275    {
00276       cerr << "NLBeamColumn2d::setDomain: Nd1: ";
00277       cerr << Nd1 << "does not exist in model\n";
00278       exit(0);
00279    }
00280 
00281    if (node2Ptr == 0) 
00282    {
00283       cerr << "NLBeamColumn2d::setDomain: Nd2: ";
00284       cerr << Nd2 << "does not exist in model\n";
00285       exit(0);
00286    }
00287 
00288    // call the DomainComponent class method 
00289    this->DomainComponent::setDomain(theDomain);
00290     
00291    // ensure connected nodes have correct number of dof's
00292    int dofNode1 = node1Ptr->getNumberDOF();
00293    int dofNode2 = node2Ptr->getNumberDOF();
00294    
00295    if ((dofNode1 !=3 ) || (dofNode2 != 3))
00296    {
00297       cerr << "NLBeamColumn2d::setDomain(): Nd2 or Nd1 incorrect dof ";
00298       exit(0);
00299    }
00300    
00301    // initialize the transformation
00302    if (crdTransf->initialize(node1Ptr, node2Ptr))
00303    {
00304       cerr << "NLBeamColumn2d::setDomain(): Error initializing coordinate transformation";  
00305       exit(0);
00306    }
00307     
00308    // get element length
00309    L = crdTransf->getInitialLength();
00310    if (L == 0)
00311    {
00312       cerr << "NLBeamColumn2d::setDomain(): Zero element length:" << this->getTag();  
00313       exit(0);
00314    }
00315    this->initializeSectionHistoryVariables();
00316    this->setSectionInterpolation();
00317    
00318    if (initialFlag == 2) {
00319      static Vector currDistrLoad(NL);
00320      currDistrLoad.Zero();  // SPECIFY LOAD HERE!!!!!!!!! 
00321      crdTransf->update();
00322      P = crdTransf->getGlobalResistingForce(Se, currDistrLoad);
00323      K = crdTransf->getGlobalStiffMatrix(kv, Se);
00324    } else
00325      this->update();
00326 }
00327 
00328 
00329 
00330 int
00331 NLBeamColumn2d::commitState()
00332 {
00333    int err = 0;
00334    int i = 0;
00335 
00336    do
00337    {
00338       vscommit[i] = vs[i];
00339       err = sections[i++]->commitState();
00340   
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 
00352    distrLoadcommit = prevDistrLoad;
00353    Uecommit = Uepr;
00354    kvcommit = kv;
00355    Secommit = Se;
00356 
00357    
00358    //   initialFlag = 0;  fmk - commented out, see what happens to Example3.1.tcl if uncommented
00359    //                         - i have not a clue why, ask remo if he ever gets in contact with us again!
00360 
00361    return err;
00362 }
00363 
00364 
00365 int NLBeamColumn2d::revertToLastCommit()
00366 {
00367    int err;
00368    int i = 0;
00369    
00370    do
00371    {
00372       vs[i] = vscommit[i];
00373       err = sections[i]->revertToLastCommit();
00374       
00375       Ssr[i] = sections[i]->getStressResultant();
00376       fs[i]  = sections[i]->getSectionFlexibility();
00377       
00378       i++;
00379    } while (err == 0 && i < nSections);
00380    
00381        
00382    if (err)
00383       return err;
00384    
00385    // revert the transformation to last commit
00386    if ((err = crdTransf->revertToLastCommit()) != 0)
00387       return err;
00388      
00389    // revert the element state to last commit
00390    prevDistrLoad = distrLoadcommit;
00391    Uepr = Uecommit;
00392    Se   = Secommit;
00393    kv   = kvcommit;
00394    
00395    // compute global resisting forces and tangent
00396    static Vector currDistrLoad(NL);
00397    currDistrLoad.Zero();  // SPECIFY LOAD HERE!!!!!!!!! 
00398    P = crdTransf->getGlobalResistingForce(Se, currDistrLoad);
00399    K = crdTransf->getGlobalStiffMatrix(kv, Se);
00400 
00401    initialFlag = 0;
00402    this->update();
00403 
00404    return err;
00405 }
00406 
00407 
00408 int NLBeamColumn2d::revertToStart()
00409 {
00410    // revert the sections state to start
00411    int err;
00412    int i = 0;
00413      
00414    do
00415    {
00416        fs[i].Zero();
00417        vs[i].Zero();
00418        Ssr[i].Zero();
00419        err = sections[i++]->revertToStart();
00420  
00421    }while (err == 0 && i < nSections);
00422 
00423    if (err)
00424       return err;
00425    
00426    // revert the transformation to start
00427    if ((err = crdTransf->revertToStart()) != 0)
00428       return err;
00429   
00430    // revert the element state to start
00431    prevDistrLoad.Zero();
00432    Uepr.Zero();
00433    Se.Zero();
00434    kv.Zero();
00435 
00436    P.Zero();
00437    K.Zero();
00438    initialFlag = 0;
00439    this->update();
00440    return err;
00441 }
00442 
00443 
00444 
00445 
00446 const Matrix &
00447 NLBeamColumn2d::getTangentStiff(void)
00448 {
00449    return K;
00450 }
00451     
00452 
00453 const Vector &
00454 NLBeamColumn2d::getResistingForce(void)
00455 {
00456    return P;
00457 }
00458 
00459 
00460 
00461 void
00462 NLBeamColumn2d::initializeSectionHistoryVariables (void)
00463 {
00464     for (int i = 0; i < nSections; i++)
00465     {
00466  int order = sections[i]->getOrder();
00467  
00468  fs[i] = Matrix(order,order);
00469  vs[i] = Vector(order);
00470         Ssr[i] = Vector(order);
00471 
00472  vscommit[i] = Vector(order);
00473     }
00474 }
00475 
00476 
00477 
00478 void
00479 NLBeamColumn2d::setSectionInterpolation (void)
00480 {
00481     GaussLobattoQuadRule1d01 quadrat(nSections);
00482     Matrix xi_pt = quadrat.getIntegrPointCoords();   
00483     
00484     for (int i = 0; i < nSections; i++)
00485     {
00486  int order = sections[i]->getOrder();
00487  const ID &code = sections[i]->getType();
00488  
00489  b[i] = Matrix(order,NEBD);
00490  this->getForceInterpolatMatrix(xi_pt(i,0), b[i], code);
00491  
00492  bp[i] = Matrix(order,NL);
00493  this->getDistrLoadInterpolatMatrix(xi_pt(i,0), bp[i], code);
00494     }
00495 }
00496 
00497 
00498 
00499 
00500 int NLBeamColumn2d::update()
00501 {
00502   // get element global end displacements
00503   static Vector Ue(NEGD);
00504   this->getGlobalDispls(Ue);
00505  
00506   // compute global end displacement increments
00507   static Vector dUe(NEGD);
00508   // dUe = Ue - Uepr
00509 
00510   dUe = Ue;
00511   dUe.addVector(1.0, Uepr,-1.0);
00512 
00513   if (dUe.Norm() != 0.0  || initialFlag == 0) {
00514       
00515     // compute distributed loads and increments
00516     static Vector currDistrLoad(NL);
00517     static Vector distrLoadIncr(NL); 
00518 
00519     currDistrLoad.Zero();  // SPECIFY LOAD HERE!!!!!!!!! 
00520     distrLoadIncr = currDistrLoad - prevDistrLoad;
00521     prevDistrLoad = currDistrLoad;
00522 
00523     // update the end displacements
00524     Uepr = Ue;
00525 
00526     // update the transformation
00527     crdTransf->update();
00528        
00529     // get basic displacements and increments
00530     static Vector v(NEBD);
00531     static Vector dv(NEBD);
00532      
00533     v = crdTransf->getBasicTrialDisp();    
00534     dv = crdTransf->getBasicIncrDeltaDisp();    
00535 
00536     // get integration point positions and weights
00537     int nIntegrPts = nSections;
00538     // GaussQuadRule1d01 quadrat(nIntegrPts);
00539     GaussLobattoQuadRule1d01 quadrat(nIntegrPts);
00540     // const Matrix &xi_pt = quadrat.getIntegrPointCoords();
00541     const Vector &weight = quadrat.getIntegrPointWeights();
00542      
00543     // numerical integration 
00544     static Vector dSs;       // section internal force increments
00545     static Vector Ss;        // section "applied" forces (in equilibrium with end forces)
00546     static Vector dvs;       // section residual deformations
00547     
00548     static Vector vr(NEBD);       // element residual displacements
00549     static Matrix f(NEBD,NEBD);   // element flexibility matrix
00550 
00551     static Matrix I(NEBD,NEBD);   // an identity matrix for matrix inverse
00552     double dW;                    // section strain energy (work) norm 
00553     int i;
00554     
00555     I.Zero();
00556     for (i=0; i<NEBD; i++)
00557       I(i,i) = 1.0;
00558 
00559     // calculate nodal force increments and update nodal forces
00560     static Vector dSe(NEBD);
00561 
00562     // dSe = kv * dv;
00563     dSe.addMatrixVector(0.0, kv, dv, 1.0);
00564 
00565     for (int j=0; j < maxIters; j++)
00566     {
00567       Se += dSe;
00568   
00569       // initialize f and vr for integration
00570       f.Zero();
00571       vr.Zero();
00572 
00573       for (i=0; i<nIntegrPts; i++)
00574       {
00575           // initialize vectors with correct size  - CHANGE LATER
00576    Ss  = Ssr[i];
00577    dSs = vs[i];
00578           dvs = vs[i];    
00579    
00580    // calculate total section forces
00581    // Ss = b*Se + bp*currDistrLoad;
00582    Ss.addMatrixVector(0.0, b[i], Se, 1.0);
00583    Ss.addMatrixVector(1.0, bp[i], currDistrLoad, 1.0);
00584 
00585    dSs = Ss;
00586    dSs.addVector(1.0, Ssr[i], -1.0);  // dSs = Ss - Ssr[i];
00587    
00588    // compute section deformation increments and update current deformations
00589    //      vs += fs * dSs;     
00590 
00591    dvs.addMatrixVector(0.0, fs[i], dSs, 1.0);
00592        
00593    // set section deformations
00594    if (initialFlag != 0)
00595           vs[i] += dvs;
00596  
00597    sections[i]->setTrialSectionDeformation(vs[i]);
00598    
00599    // get section resisting forces
00600    Ssr[i] = sections[i]->getStressResultant();
00601    
00602    // get section flexibility matrix
00603           fs[i] = sections[i]->getSectionFlexibility();
00604    
00605    // calculate section residual deformations
00606    // dvs = fs * (Ss - Ssr);
00607    
00608    dSs = Ss;
00609    dSs.addVector(1.0, Ssr[i], -1.0);  // dSs = Ss - Ssr[i];
00610           
00611    dvs.addMatrixVector(0.0, fs[i], dSs, 1.0);
00612        
00613           // integrate element flexibility matrix
00614    // f = f + (b^ fs * b) * weight(i);
00615           //cout << "b[" << i << "]:" << b[i];
00616          f.addMatrixTripleProduct(1.0, b[i], fs[i], weight(i));
00617 
00618    // integrate residual deformations
00619    // vr += (b^ (vs + dvs)) * weight(i);
00620    vr.addMatrixTransposeVector(1.0, b[i], vs[i] + dvs, weight(i));
00621       }  
00622       
00623       f  *= L;
00624       vr *= L;
00625 
00626       // calculate element stiffness matrix
00627       // invert3by3Matrix(f, kv);
00628 
00629       if (f.Solve(I,kv) < 0)
00630   g3ErrorHandler->warning("NLBeamColumn3d::updateElementState() - could not invert flexibility\n");
00631 
00632       dv = v - vr;
00633 
00634       // dSe = kv * dv;
00635       dSe.addMatrixVector(0.0, kv, dv, 1.0);
00636       
00637       dW = dv ^ dSe;
00638       if (fabs(dW) < tol)
00639         break;
00640     }     
00641       
00642     // determine resisting forces
00643     Se += dSe;
00644 
00645     // get resisting forces and stiffness matrix in global coordinates
00646     P = crdTransf->getGlobalResistingForce(Se, currDistrLoad);
00647     K = crdTransf->getGlobalStiffMatrix(kv, Se);
00648 
00649     initialFlag = 1;
00650 
00651     return 1;
00652   }
00653   
00654   else
00655     return 0;
00656 }
00657 
00658 
00659 
00660 void NLBeamColumn2d::getGlobalDispls(Vector &dg) const
00661 {
00662    // determine global displacements
00663    const Vector &disp1 = node1Ptr->getTrialDisp();
00664    const Vector &disp2 = node2Ptr->getTrialDisp();
00665 
00666    for (int i = 0; i < NND; i++)
00667    {
00668       dg(i)     = disp1(i);
00669       dg(i+NND) = disp2(i);
00670    }
00671 }
00672 
00673 
00674 
00675 void NLBeamColumn2d::getGlobalAccels(Vector &ag) const
00676 {
00677    // determine global displacements
00678    const Vector &accel1 = node1Ptr->getTrialAccel();
00679    const Vector &accel2 = node2Ptr->getTrialAccel();
00680 
00681    for (int i = 0; i < NND; i++)
00682    {
00683       ag(i)     = accel1(i);
00684       ag(i+NND) = accel2(i);
00685    }
00686 }
00687 
00688 
00689 
00690 void NLBeamColumn2d::getForceInterpolatMatrix(double xi, Matrix &b, const ID &code)
00691 {
00692    b.Zero();
00693 
00694    for (int i = 0; i < code.Size(); i++)
00695    {
00696       switch (code(i))
00697       {
00698          case SECTION_RESPONSE_MZ:  // Moment, Mz, interpolation
00699      b(i,1) = xi - 1.0;
00700      b(i,2) = xi;
00701      break;
00702   case SECTION_RESPONSE_P:  // Axial, P, interpolation
00703      b(i,0) = 1.0;
00704      break;
00705   case SECTION_RESPONSE_VY:  // Shear, Vy, interpolation
00706      b(i,1) = 1.0/L;
00707      b(i,2) = 1.0/L;
00708      break;
00709   default:
00710      break;
00711       }
00712    }
00713 }
00714 
00715 
00716 void NLBeamColumn2d::getDistrLoadInterpolatMatrix(double xi, Matrix &bp, const ID &code)
00717 {
00718    bp.Zero();
00719 
00720    for (int i = 0; i < code.Size(); i++)
00721    {
00722       switch (code(i))
00723       {
00724          case SECTION_RESPONSE_MZ:  // Moment, Mz, interpolation
00725      bp(i,1) = xi*(xi-1)*L*L/2;
00726      break;
00727   case SECTION_RESPONSE_P:  // Axial, P, interpolation
00728      bp(i,0) = (1-xi)*L;
00729      break;
00730   case SECTION_RESPONSE_VY:  // Shear, Vy, interpolation
00731      bp(i,1) = (xi-0.5)*L;
00732      break;
00733   default:
00734      break;
00735       }
00736    }
00737 }
00738 
00739 
00740 const Matrix &
00741 NLBeamColumn2d::getSecantStiff(void)
00742 {
00743     // TO DO
00744     return this->getTangentStiff();
00745 }
00746 
00747     
00748 const Matrix &
00749 NLBeamColumn2d::getDamp(void)
00750 {
00751     return d; // zero matrix still
00752 }
00753 
00754 
00755 const Matrix &
00756 NLBeamColumn2d::getMass(void)
00757 { 
00758     // get element length and orientation
00759     m(0,0) = m(1,1) = m(3,3) = m(4,4) = rho * L/2;
00760    
00761     return m;
00762 }
00763 
00764 
00765 
00766 void 
00767 NLBeamColumn2d::zeroLoad(void)
00768 {
00769     load.Zero();
00770 }
00771 
00772 int
00773 NLBeamColumn2d::addLoad(const Vector &moreLoad)
00774 {
00775     if (moreLoad.Size() != 6) {
00776  cerr << "NLBeamColumn2d::addLoad: vector not of correct size\n";
00777  return -1;
00778     }
00779     load += moreLoad;
00780     return 0;
00781 }
00782 
00783 
00784 const Vector &
00785 NLBeamColumn2d::getResistingForceIncInertia()
00786 { 
00787     Vector f(NEGD);
00788     Vector ag(NEGD);
00789     
00790     f = this->getResistingForce();
00791     this->getMass();
00792     this->getGlobalAccels(ag);
00793     
00794     // Pinert = f -  m * ag;
00795     Pinert = f;
00796     Pinert.addMatrixVector(1.0, m, ag, -1.0); 
00797     
00798     return Pinert;
00799 }
00800 
00801 
00802 
00803 bool
00804 NLBeamColumn2d::isSubdomain(void)
00805 {
00806     return false;
00807 }
00808 
00809 
00810 
00811 int
00812 NLBeamColumn2d::sendSelf(int commitTag, Channel &theChannel)
00813 {  
00814   // place the integer data into an ID
00815 
00816   int dbTag = this->getDbTag();
00817   int i, j , k;
00818   int loc = 0;
00819   
00820   static ID idData(9);  // one bigger than needed so no clash later
00821   idData(0) = this->getTag();
00822   idData(1) = connectedExternalNodes(0);
00823   idData(2) = connectedExternalNodes(1);
00824   idData(3) = nSections;
00825   idData(4) = maxIters;
00826   idData(5) = initialFlag;
00827   idData(6) = crdTransf->getClassTag();
00828   int crdTransfDbTag  = crdTransf->getDbTag();
00829   if (crdTransfDbTag  == 0) {
00830       crdTransfDbTag = theChannel.getDbTag();
00831       if (crdTransfDbTag  != 0) {
00832     crdTransf->setDbTag(crdTransfDbTag);
00833        }
00834   }
00835   idData(7) = crdTransfDbTag;
00836   
00837 
00838   if (theChannel.sendID(dbTag, commitTag, idData) < 0)  
00839   {
00840      g3ErrorHandler->warning("NLBeamColumn2d::sendSelf() - %s\n",
00841              "failed to send ID data");
00842      return -1;
00843   }    
00844   
00845   if (crdTransf->sendSelf(commitTag, theChannel) < 0)  
00846   {
00847      g3ErrorHandler->warning("NLBeamColumn2d::sendSelf() - %s\n",
00848              "failed to send crdTranf");
00849      return -1;
00850   }      
00851 
00852   
00853   //
00854   // send an ID for the sections containing each sections dbTag and classTag
00855   // if section ha no dbTag get one and assign it
00856   //
00857 
00858   ID idSections(2*nSections);
00859   loc = 0;
00860   for (i = 0; i<nSections; i++) 
00861   {
00862     int sectClassTag = sections[i]->getClassTag();
00863     int sectDbTag = sections[i]->getDbTag();
00864     if (sectDbTag == 0) 
00865     {
00866       sectDbTag = theChannel.getDbTag();
00867       sections[i]->setDbTag(sectDbTag);
00868     }
00869 
00870     idSections(loc) = sectClassTag;
00871     idSections(loc+1) = sectDbTag;
00872     loc += 2;
00873   }
00874 
00875   if (theChannel.sendID(dbTag, commitTag, idSections) < 0)  {
00876     g3ErrorHandler->warning("NLBeamColumn2d::sendSelf() - %s\n",
00877        "failed to send ID data");
00878     return -1;
00879   }    
00880 
00881   //
00882   // send the sections
00883   //
00884   
00885   for (j = 0; j<nSections; j++) {
00886     if (sections[j]->sendSelf(commitTag, theChannel) < 0) {
00887       g3ErrorHandler->warning("NLBeamColumn2d::sendSelf() - section %d %s\n",
00888          j,"failed to send itself");
00889       return -1;
00890     }
00891   }
00892   
00893   // into a vector place distrLoadCommit, rho, UeCommit, Secommit and kvcommit
00894   int secDefSize = 0;
00895   int secFlexSize = 0;
00896   for (i = 0; i < nSections; i++)
00897   {
00898      int size = sections[i]->getOrder();
00899      secDefSize   += size;
00900      secFlexSize  += size*size;
00901   }
00902 
00903   
00904   
00905   static Vector dData(1+1+NL+NEGD+NEBD+NEBD*NEBD+secDefSize+secFlexSize); 
00906   loc = 0;
00907 
00908   // place double variables into Vector
00909   dData(loc++) = rho;
00910   dData(loc++) = tol;
00911   
00912   // put  distrLoadCommit into the Vector
00913   for (i=0; i<NL; i++) 
00914     dData(loc++) = distrLoadcommit(i);
00915 
00916   // place UeCommit into Vector
00917   for (i=0; i<NEGD; i++)
00918     dData(loc++) = Uecommit(i);
00919 
00920   // place kvcommit into vector
00921   for (i=0; i<NEBD; i++) 
00922     dData(loc++) = Secommit(i);
00923 
00924   // place kvcommit into vector
00925   for (i=0; i<NEBD; i++) 
00926      for (j=0; j<NEBD; j++)
00927         dData(loc++) = kvcommit(i,j);
00928   
00929   // place vscommit into vector
00930   for (k=0; k<nSections; k++)
00931      for (i=0; i<sections[k]->getOrder(); i++)
00932  dData(loc++) = (vscommit[k])(i);
00933 
00934   
00935   if (theChannel.sendVector(dbTag, commitTag, dData) < 0) {
00936      g3ErrorHandler->warning("NLBeamColumn2d::sendSelf() - %s\n",
00937          "failed to send Vector data");
00938      return -1;
00939   }    
00940 
00941   return 0;
00942 }    
00943 
00944 
00945 int
00946 NLBeamColumn2d::recvSelf(int commitTag, Channel &theChannel, FEM_ObjectBroker &theBroker)
00947 {
00948    //
00949   // into an ID of size 7 place the integer data
00950   //
00951   int dbTag = this->getDbTag();
00952   int i,j,k;
00953   
00954   static ID idData(9); // one bigger than needed 
00955 
00956   if (theChannel.recvID(dbTag, commitTag, idData) < 0)  {
00957     g3ErrorHandler->warning("NLBeamColumn2d::recvSelf() - %s\n",
00958        "failed to recv ID data");
00959     return -1;
00960   }    
00961 
00962   this->setTag(idData(0));
00963   connectedExternalNodes(0) = idData(1);
00964   connectedExternalNodes(1) = idData(2);
00965   maxIters = idData(4);
00966   initialFlag = idData(5);
00967   
00968   int crdTransfClassTag = idData(6);
00969   int crdTransfDbTag = idData(7);
00970 
00971   // create a new crdTransf object if one needed
00972   if (crdTransf == 0 || crdTransf->getClassTag() != crdTransfClassTag) {
00973       if (crdTransf != 0)
00974    delete crdTransf;
00975 
00976       crdTransf = theBroker.getNewCrdTransf2d(crdTransfClassTag);
00977 
00978       if (crdTransf == 0) {
00979    g3ErrorHandler->warning("NLBeamColumn2d::recvSelf() - %s %d\n",
00980       "failed to obtain a CrdTrans object with classTag",
00981       crdTransfClassTag);
00982    return -2;   
00983       }
00984   }
00985 
00986   crdTransf->setDbTag(crdTransfDbTag);
00987 
00988   // invoke recvSelf on the crdTransf obkject
00989   if (crdTransf->recvSelf(commitTag, theChannel, theBroker) < 0)  
00990   {
00991      g3ErrorHandler->warning("NLBeamColumn2d::sendSelf() - %s\n",
00992              "failed to recv crdTranf");
00993      return -3;
00994   }      
00995   
00996   //
00997   // recv an ID for the sections containing each sections dbTag and classTag
00998   //
00999 
01000   ID idSections(2*idData(3));
01001   int loc = 0;
01002 
01003   if (theChannel.recvID(dbTag, commitTag, idSections) < 0)  {
01004     g3ErrorHandler->warning("NLBeamColumn2d::recvSelf() - %s\n",
01005        "failed to recv ID data");
01006     return -1;
01007   }    
01008 
01009   //
01010   // now receive the sections
01011   //
01012   
01013   if (nSections != idData(3)) {
01014 
01015     //
01016     // we do not have correct number of sections, must delete the old and create
01017     // new ones before can recvSelf on the sections
01018     //
01019 
01020     // delete the old
01021     if (nSections != 0) {
01022       for (int i=0; i<nSections; i++)
01023  delete sections[i];
01024       delete [] sections;
01025     }
01026 
01027     // create a new array to hold pointers
01028     sections = new SectionForceDeformation *[idData(3)];
01029     if (sections == 0) {
01030       g3ErrorHandler->fatal("NLBeamColumn2d::recvSelf() - %s %d\n",
01031          "out of memory creating sections array of size",idData(3));
01032       return -1;
01033     }    
01034 
01035     // create a section and recvSelf on it
01036     nSections = idData(3);
01037     loc = 0;
01038     
01039     for (i=0; i<nSections; i++) {
01040       int sectClassTag = idSections(loc);
01041       int sectDbTag = idSections(loc+1);
01042       loc += 2;
01043       sections[i] = theBroker.getNewSection(sectClassTag);
01044       if (sections[i] == 0) {
01045  g3ErrorHandler->fatal("NLBeamColumn2d::recvSelf() - %s %d\n",
01046          "Broker could not create Section of class type",sectClassTag);
01047  return -1;
01048       }
01049       sections[i]->setDbTag(sectDbTag);
01050       if (sections[i]->recvSelf(commitTag, theChannel, theBroker) < 0) {
01051  g3ErrorHandler->warning("NLBeamColumn2d::recvSelf() - section %d %s\n",
01052     i,"failed to recv itself");
01053  return -1;
01054       }     
01055     }
01056 
01057   } else {
01058 
01059     // 
01060     // for each existing section, check it is of correct type
01061     // (if not delete old & create a new one) then recvSelf on it
01062     //
01063     
01064     loc = 0;
01065     for (i=0; i<nSections; i++) {
01066       int sectClassTag = idSections(loc);
01067       int sectDbTag = idSections(loc+1);
01068       loc += 2;
01069 
01070       // check of correct type
01071       if (sections[i]->getClassTag() !=  sectClassTag) {
01072  // delete the old section[i] and create a new one
01073  delete sections[i];
01074  sections[i] = theBroker.getNewSection(sectClassTag);
01075  if (sections[i] == 0) {
01076    g3ErrorHandler->fatal("NLBeamColumn2d::recvSelf() - %s %d\n",
01077     "Broker could not create Section of class type",sectClassTag);
01078    return -1;
01079  }
01080       }
01081 
01082       // recvvSelf on it
01083       sections[i]->setDbTag(sectDbTag);
01084       if (sections[i]->recvSelf(commitTag, theChannel, theBroker) < 0) {
01085  g3ErrorHandler->warning("NLBeamColumn2d::recvSelf() - section %d %s\n",
01086     i,"failed to recv itself");
01087  return -1;
01088       }     
01089     }
01090   }
01091   
01092   
01093   // into a vector place distrLoadCommit, rho, UeCommit, Secommit and kvcommit
01094   int secDefSize = 0;
01095   int secFlexSize = 0;
01096   for (int ii = 0; ii < nSections; ii++)
01097   {
01098      int size = sections[ii]->getOrder();
01099      secDefSize   += size;
01100      secFlexSize  += size*size;
01101   }
01102   
01103   static Vector dData(1+1+NL+NEGD+NEBD+NEBD*NEBD+secDefSize+secFlexSize);   
01104   
01105   if (theChannel.recvVector(dbTag, commitTag, dData) < 0)  {
01106     g3ErrorHandler->warning("NLBeamColumn2d::sendSelf() - %s\n",
01107        "failed to send Vector data");
01108     return -1;
01109   }    
01110   
01111   loc = 0;
01112   
01113   // place double variables into Vector
01114   rho = dData(loc++);
01115   tol = dData(loc++);
01116 
01117   // put  distrLoadCommit into the Vector
01118   for (i=0; i<NL; i++) 
01119     distrLoadcommit(i) = dData(loc++);
01120 
01121   // place UeCommit into Vector
01122   for (i=0; i<NEGD; i++)
01123     Uecommit(i) = dData(loc++);
01124 
01125   // place kvcommit into vector
01126   for (i=0; i<NEBD; i++) 
01127     Secommit(i) = dData(loc++);
01128 
01129   // place kvcommit into vector
01130   for (i=0; i<NEBD; i++) 
01131      for (j=0; j<NEBD; j++)
01132         kvcommit(i,j) = dData(loc++);
01133 
01134   prevDistrLoad = distrLoadcommit;
01135   Uepr = Uecommit;
01136   kv   = kvcommit;
01137   Se   = Secommit;
01138 
01139   // Delete the old
01140   if (vscommit != 0)
01141     delete [] vscommit;
01142 
01143   // Allocate the right number
01144   vscommit = new Vector[nSections];
01145   if (vscommit == 0) {
01146     g3ErrorHandler->warning("%s -- failed to allocate vscommit array",
01147        "NLBeamColumn2d::recvSelf");
01148     return -1;
01149   }
01150 
01151   for (k = 0; k < nSections; k++) {
01152     int order = sections[k]->getOrder();
01153 
01154     // place vscommit into vector
01155     vscommit[k] = Vector(order);
01156     for (i = 0; i < order; i++)
01157       (vscommit[k])(i) = dData(loc++);
01158   }
01159  
01160   // Delete the old
01161   if (fs != 0)
01162     delete [] fs;
01163 
01164   // Allocate the right number
01165   fs = new Matrix[nSections];  
01166   if (fs == 0) {
01167     g3ErrorHandler->warning("%s -- failed to allocate fs array",
01168        "NLBeamColumn2d::recvSelf");
01169     return -1;
01170   }
01171    
01172   // Delete the old
01173   if (vs != 0)
01174     delete [] vs;
01175 
01176   // Allocate the right number
01177   vs = new Vector[nSections];  
01178   if (vs == 0) {
01179     g3ErrorHandler->warning("%s -- failed to allocate vs array",
01180        "NLBeamColumn2d::recvSelf");
01181     return -1;
01182   }
01183  
01184   // Delete the old
01185   if (Ssr != 0)
01186     delete [] Ssr;
01187 
01188   // Allocate the right number
01189   Ssr = new Vector[nSections];  
01190   if (Ssr == 0) {
01191     g3ErrorHandler->warning("%s -- failed to allocate Ssr array",
01192        "NLBeamColumn2d::recvSelf");
01193     return -1;
01194   }
01195 
01196   // Set up section history variables 
01197   this->initializeSectionHistoryVariables();
01198 
01199   // Delete the old
01200   if (b != 0)
01201     delete [] b;
01202 
01203   // Allocate the right number
01204   b = new Matrix[nSections];  
01205   if (b == 0) {
01206     g3ErrorHandler->warning("%s -- failed to allocate b array",
01207        "NLBeamColumn2d::recvSelf");
01208     return -1;
01209   }
01210 
01211   // Delete the old
01212   if (bp != 0)
01213     delete [] bp;
01214 
01215   // Allocate the right number
01216   bp = new Matrix[nSections];  
01217   if (bp == 0) {
01218     g3ErrorHandler->warning("%s -- failed to allocate bp array",
01219        "NLBeamColumn2d::recvSelf");
01220     return -1;
01221   }
01222 
01223   // Set up section force interpolation matrices
01224   this->setSectionInterpolation();
01225 
01226   if (node1Ptr != 0) {
01227      static Vector currDistrLoad(NL);
01228      currDistrLoad.Zero();  // SPECIFY LOAD HERE!!!!!!!!! 
01229      crdTransf->update();
01230      P = crdTransf->getGlobalResistingForce(Se, currDistrLoad);
01231      K = crdTransf->getGlobalStiffMatrix(kv, Se);
01232   }
01233 
01234   initialFlag = 2;  
01235 
01236   return 0;
01237 }
01238 
01239 
01240 
01241 
01242 void NLBeamColumn2d::compSectionDisplacements(Vector sectionCoords[], Vector sectionDispls[]) const
01243 {
01244 
01245    // update the transformation
01246    crdTransf->update();
01247        
01248    // get basic displacements and increments
01249    static Vector ub(NEBD);
01250    ub = crdTransf->getBasicTrialDisp();    
01251   
01252    // get integration point positions and weights
01253    int nIntegrPts = nSections;
01254    GaussLobattoQuadRule1d01 quadrat(nIntegrPts);
01255    const Matrix &xi_pt  = quadrat.getIntegrPointCoords();
01256 
01257    // setup Vandermode and CBDI influence matrices
01258    int i;
01259    double xi;
01260  
01261    // get CBDI influence matrix
01262    Matrix ls(nIntegrPts, nIntegrPts);
01263    getCBDIinfluenceMatrix(nIntegrPts, xi_pt, L, ls);
01264 
01265    // get section curvatures
01266    Vector kappa(nIntegrPts);  // curvature
01267    Vector vs;              // section deformations 
01268 
01269    for (i=0; i<nIntegrPts; i++)
01270    {
01271        // THIS IS VERY INEFFICIENT ... CAN CHANGE LATER
01272        int sectionKey = 0;
01273        const ID &code = sections[i]->getType();
01274        int ii;
01275        for (ii = 0; ii < code.Size(); ii++)
01276     if (code(ii) == SECTION_RESPONSE_MZ)
01277     {
01278         sectionKey = ii;
01279         break;
01280     }
01281 
01282        if (ii == code.Size())
01283     g3ErrorHandler->fatal("FATAL NLBeamColumn2d::compSectionDispls - section does not provide Mz response\n");
01284    
01285        // get section deformations
01286        vs = sections[i]->getSectionDeformation();
01287        kappa(i) = vs(sectionKey);
01288    }
01289 
01290        //cerr << "kappa: " << kappa;   
01291 
01292    Vector w(nIntegrPts);
01293    static Vector xl(NDM), uxb(NDM);
01294    static Vector xg(NDM), uxg(NDM); 
01295 
01296    // w = ls * kappa;  
01297    w.addMatrixVector (0.0, ls, kappa, 1.0);
01298    
01299    for (i=0; i<nSections; i++)
01300    {
01301       xi = xi_pt(i,0);
01302 
01303       xl(0) = xi * L;
01304       xl(1) = 0;
01305 
01306       // get section global coordinates
01307       sectionCoords[i] = crdTransf->getPointGlobalCoordFromLocal(xl);
01308 
01309       // compute section displacements
01310       uxb(0) = xi * ub(0); // consider linear variation for axial displacement. CHANGE LATER!!!!!!!!!!
01311       uxb(1) = w(i);
01312              
01313       // get section displacements in global system 
01314       sectionDispls[i] = crdTransf->getPointGlobalDisplFromBasic(xi, uxb);
01315    }        
01316 }
01317 
01318    
01319 
01320 
01321 
01322 void
01323 NLBeamColumn2d::Print(ostream &s, int flag)
01324 {
01325    if (flag == 1)
01326    { 
01327       s << "\nElement: " << this->getTag() << " Type: NLBeamColumn2d ";
01328       s << "\tConnected Nodes: " << connectedExternalNodes ;
01329       s << "\tNumber of Sections: " << nSections;
01330       s << "\tMass density: " << rho;
01331     
01332       for (int i = 0; i < nSections; i++)
01333          s << "\nSection "<<i<<" :" << *sections[i];
01334  
01335       s << "\tStiffness Matrix:\n" << K;
01336       s << "\tResisting Force: " << P;
01337    }
01338    else
01339    {
01340       s << "\nElement: " << this->getTag() << " Type: NLBeamColumn2d ";
01341       s << "\tConnected Nodes: " << connectedExternalNodes ;
01342       s << "\tNumber of Sections: " << nSections;
01343       s << "\tMass density: " << rho << endl;
01344       static Vector force(6);
01345       force(3) = Secommit(0);
01346       force(0) = -Secommit(0);
01347       force(2) = Secommit(1);
01348       force(5) = Secommit(2);
01349       double V = (Secommit(1)+Secommit(2))/L;
01350       force(1) = V;
01351       force(4) = -V;
01352       s << "\tEnd 1 Forces (P V M): "
01353    << force(0) << ' ' << force(1) << ' ' << force(2) << endl;
01354       s << "\tEnd 2 Forces (P V M): "
01355    << force(3) << ' ' << force(4) << ' ' << force(5) << endl;
01356       s << "\tResisting Force: " << P;
01357    }
01358 }
01359 
01360 
01361 ostream &operator<<(ostream &s, NLBeamColumn2d &E)
01362 {
01363     E.Print(s);
01364     return s;
01365 }
01366 
01367 
01368 
01369 int
01370 NLBeamColumn2d::displaySelf(Renderer &theViewer, int displayMode, float fact)
01371 {
01372   if (displayMode == 2) {
01373     // first determine the end points of the beam based on
01374     // the display factor (a measure of the distorted image)
01375     const Vector &end1Crd = node1Ptr->getCrds();
01376     const Vector &end2Crd = node2Ptr->getCrds(); 
01377 
01378     const Vector &end1Disp = node1Ptr->getDisp();
01379     const Vector &end2Disp = node2Ptr->getDisp();
01380 
01381  static Vector v1(3);
01382  static Vector v2(3);
01383 
01384  for (int i = 0; i < 2; i++) {
01385   v1(i) = end1Crd(i) + end1Disp(i)*fact;
01386   v2(i) = end2Crd(i) + end2Disp(i)*fact;    
01387  }
01388  
01389  return theViewer.drawLine (v1, v2, 1.0, 1.0);
01390   }
01391    
01392   else if (displayMode == 1) 
01393    {
01394        // first determine the two end points of the element based on
01395        //  the display factor (a measure of the distorted image)
01396     
01397        static Vector v1(3), v2(3);
01398 
01399        const Vector &node1Crd = node1Ptr->getCrds();
01400        const Vector &node2Crd = node2Ptr->getCrds(); 
01401        const Vector &node1Disp = node1Ptr->getDisp();
01402        const Vector &node2Disp = node2Ptr->getDisp();    
01403 
01404        v1(2) = 0.0;
01405        v2(2) = 0.0;
01406               
01407        
01408        int i;
01409        
01410        // allocate array of vectors to store section coordinates and displacements
01411        
01412        Vector *coords = new Vector [nSections];
01413      
01414        if (!coords)
01415        {
01416     cerr << "NLBeamColumn2d::displaySelf() -- failed to allocate coords array";   
01417     exit(-1);
01418        }
01419        
01420        for (i = 0; i < nSections; i++)
01421    coords[i] = Vector(2);
01422        
01423        Vector *displs = new Vector [nSections];
01424      
01425        if (!displs)
01426        {
01427     cerr << "NLBeamColumn2d::displaySelf() -- failed to allocate coords array";   
01428     exit(-1);
01429        }
01430 
01431        for (i = 0; i < nSections; i++)
01432    displs[i] = Vector(2);
01433        
01434        int error;
01435        
01436        this->compSectionDisplacements(coords, displs);
01437 
01438        v1(0) = node1Crd(0) + node1Disp(0)*fact;
01439        v1(1) = node1Crd(1) + node1Disp(1)*fact;
01440  
01442 
01443        // get global displacements and coordinates of each section          
01444 
01445        for (i=0; i<nSections; i++) 
01446        {
01447     
01448           v2(0) = (coords[i])(0) + ((displs[i])(0))*fact;
01449           v2(1) = (coords[i])(1) + ((displs[i])(1))*fact;
01450        
01451           error = theViewer.drawLine(v1, v2, 1.0, 1.0);
01452    
01453           if (error)
01454             return error;
01455           v1 = v2;
01456 
01457        }
01458        
01459        v2(0) = node2Crd(0) + node2Disp(0)*fact;
01460        v2(1) = node2Crd(1) + node2Disp(1)*fact;
01461        
01462        error = theViewer.drawLine(v1, v2, 1.0, 1.0);
01463 
01464        delete [] displs;
01465 
01466        if (error)
01467    return error;
01468    } 
01469    
01470    else if (displayMode == 2) 
01471    {
01472 /*
01473        v1(2) = 0.0;
01474        v2(2) = 0.0;
01475 
01476        // get element length and orientation
01477        this->getElementLengthAndOrientation();
01478 
01479        // get element global end displacements
01480        Vector Ue(6);
01481        this->getGlobalDispls(Ue);
01482        
01483        // get matrix that transforms displacements from global to 
01484        // local coordinates
01485        Matrix Tgl(6,6);
01486        this->getTransfMatrixLocalGlobal(Tgl);
01487 
01488        // transform global end displacements to  local coordinates
01489        Vector u(6);
01490        u = Tgl *  Ue;
01491 
01492        double u1, u2, u4, u5;
01493        u1 = u(0);
01494        u2 = u(1);
01495        u4 = u(3);
01496        u5 = u(4);
01497 
01498        // subdivide element into smaller parts to draw the deformed shape
01499        double x_i, y_i, xg_xi0, yg_xi0, xi, ul_xi, wl_xi;
01500        x_i = node1Crd(0);
01501        y_i = node1Crd(1);
01502              
01503        // determine displaced position of node i      
01504        xg_xi0 = x_i + Ue(0) * fact;
01505        yg_xi0 = y_i + Ue(1) * fact;
01506 
01507        // get integration point positions and weights
01508        int nIntegrPts = nSections;
01509        GaussLobattoQuadRule1d01 quadrat(nIntegrPts);
01510        Matrix xi_pt = quadrat.getIntegrPointCoords();
01511        Vector weight = quadrat.getIntegrPointWeights();
01512 
01513        // setup Vandermode and CBDI influence matrices
01514        int i, j, k, i0, j0;
01515        Matrix G(nIntegrPts, nIntegrPts);
01516        Matrix invG(nIntegrPts, nIntegrPts);
01517     
01518        for (i = 1; i <= nIntegrPts; i++)
01519     for (j = 1; j <= nIntegrPts; j++)
01520     {
01521         i0 = i - 1;
01522         j0 = j - 1;
01523         xi = xi_pt(i0,0);
01524         G(i0,j0) =  pow(xi,j-1);
01525     }
01526        invertMatrix(nIntegrPts, G, invG);
01527         
01528        // get section curvatures
01529        Vector kappa(nIntegrPts);  // curvature
01530        Vector vs;              // section deformations 
01531        for (i=0; i<nIntegrPts; i++)
01532        {
01533     // THIS IS VERY INEFFICIENT ... CAN CHANGE IF RUNS TOO SLOW
01534     int sectionKey = 0;
01535     const ID &code = sections[i]->getType();
01536     int ii;
01537     for (ii = 0; ii < code.Size(); ii++)
01538         if (code(ii) == SECTION_RESPONSE_MZ)
01539         {
01540      sectionKey = ii;
01541      break;
01542         }
01543     
01544     if (ii == code.Size())
01545         g3ErrorHandler->fatal("FATAL NLBeamColumn2d::displaySelf - section does not provide Mz response\n");
01546     
01547     // get section deformations
01548     vs = sections[i]->getSectionDeformation();
01549     kappa(i) = vs(sectionKey);
01550        }
01551 
01552        //cerr << "kappa: " << kappa;
01553 
01554        int ns = 20;    
01555 
01556        Vector lbar(nIntegrPts);
01557        Vector ls(nIntegrPts);
01558        double xl_xi, yl_xi, xg_xi, yg_xi;
01559        double lskappa = 0;
01560        int error;
01561      
01562        for (i = 1; i<= ns; i++)
01563        {
01564            xi = ((double) i)/ns;
01565         
01566     // evaluate CBDI matrix
01567            for (j = 1; j<= nIntegrPts; j++)
01568        lbar(j-1) = (pow(xi,j+1) - xi)/(j*(j+1));
01569         
01570            for (k = 0; k < nIntegrPts; k++)
01571            {
01572               ls(k) = 0;
01573               for (j = 0; j < nIntegrPts; j++)
01574    ls(k) += (L*L) * lbar(j) * invG(j,k);
01575            }
01576 
01577     lskappa = 0;
01578     for (j = 0; j < nIntegrPts; j++)
01579        lskappa += ls(j) * kappa(j);
01580        
01581            // calculate displacements of the point xi in local coordinates
01582     wl_xi = lskappa  + (1-xi)*u2 + xi*u5;
01583            ul_xi =  (1-xi)*u1 + xi*u4; // consider linear variation$
01584                                     // CHANGE LATER!!!!!!!!!!
01585         
01586            // determine displaced local coordinates of the point xi
01587            xl_xi = L * xi + ul_xi * fact;
01588            yl_xi =          wl_xi * fact;
01589     
01590     // rotate to global coordinates
01591     xg_xi = cosTheta * xl_xi - sinTheta * yl_xi;
01592     yg_xi = sinTheta * xl_xi + cosTheta * yl_xi;
01593         
01594     // translate to global coordinates
01595     xg_xi = xg_xi + x_i;
01596     yg_xi = yg_xi + y_i;
01597       
01598            // draw the displaced position of this line segment
01599            v1(0) = xg_xi0;
01600            v1(1) = yg_xi0;
01601         
01602            v2(0) = xg_xi;
01603            v2(1) = yg_xi;
01604   
01605            error =  theViewer.drawLine(v1, v2, 1.0, 1.0); 
01606         
01607     if (error)
01608         return error;
01609         
01610     xg_xi0 = xg_xi;
01611     yg_xi0 = yg_xi;
01612        }
01613               
01614        return error;
01615   */ 
01616     } 
01617     else if (displayMode == 3)
01618     {  
01619  
01620        // plot the curvatures
01621        // first determine the two end points of the element based on
01622        //  the display factor (a measure of the distorted image)
01623     
01624        static Vector v1(NDM), v2(NDM);
01625 
01626        const Vector &node1Crd = node1Ptr->getCrds();
01627        const Vector &node2Crd = node2Ptr->getCrds(); 
01628        const Vector &node1Disp = node1Ptr->getDisp();
01629        const Vector &node2Disp = node2Ptr->getDisp();    
01630 
01631        v1(2) = 0.0;
01632        v2(2) = 0.0;
01633 
01634        // subdivide element into smaller parts to draw the deformed shape
01635        double x_i, y_i, x_j, y_j, xg_xi0, yg_xi0, xi;
01636        x_i = node1Crd(0);
01637        y_i = node1Crd(1);
01638        x_j = node2Crd(0);
01639        y_j = node2Crd(1);
01640        
01641        // determine displaced position of node i      
01642        xg_xi0 = x_i;
01643        yg_xi0 = y_i;
01644 
01645        // get integration point positions and weights
01646        int nIntegrPts = nSections;
01647        GaussLobattoQuadRule1d01 quadrat(nIntegrPts);
01648        Matrix xi_pt = quadrat.getIntegrPointCoords();
01649        Vector weight = quadrat.getIntegrPointWeights();
01650 
01651        // get section curvatures
01652        Vector kappa(nIntegrPts); // curvature
01653        Vector vs; // section deformations 
01654     int i;
01655         for (i=0; i<nIntegrPts; i++)
01656   {
01657    // THIS IS VERY INEFFICIENT ... CAN CHANGE IF RUNS TOO SLOW
01658    int sectionKey = 0;
01659    const ID &code = sections[i]->getType();
01660    int ii;
01661    for (ii = 0; ii < code.Size(); ii++)
01662     if (code(ii) == SECTION_RESPONSE_MZ)
01663     {
01664      sectionKey = ii;
01665      break;
01666     }
01667 
01668    if (ii == code.Size())
01669     g3ErrorHandler->fatal("FATAL NLBeamColumn2d::displaySelf - section does not provide Mz response\n");
01670    
01671    // get section deformations
01672    vs = sections[i]->getSectionDeformation();
01673    kappa(i) = vs(sectionKey);
01674   }
01675 
01676        double xl_xi, yl_xi, xg_xi, yg_xi;
01677        int error;
01678      
01679        for (i = 0; i< nIntegrPts; i++)
01680        {
01681          xi = xi_pt(i,0);
01682         
01683         // determine displaced local coordinates of the point xi
01684         xl_xi = L * xi;
01685         yl_xi = kappa(i) * fact;
01686     
01687         // rotate to global coordinates
01688         xg_xi = cosTheta * xl_xi - sinTheta * yl_xi;
01689         yg_xi = sinTheta * xl_xi + cosTheta * yl_xi;
01690         
01691         // translate to global coordinates
01692         xg_xi = xg_xi + x_i;
01693         yg_xi = yg_xi + y_i;
01694       
01695         // draw the displaced position of this line segment
01696         v1(0) = xg_xi0;
01697         v1(1) = yg_xi0;
01698         
01699         v2(0) = xg_xi;
01700         v2(1) = yg_xi;
01701 
01702         error =  theViewer.drawLine(v1, v2, 1.0, 1.0); 
01703         
01704         if (error)
01705      return error;
01706         
01707         xg_xi0 = xg_xi;
01708         yg_xi0 = yg_xi;
01709       }
01710 
01711       v1(0) = xg_xi0;
01712       v1(1) = yg_xi0;
01713       v2(0) = x_j;
01714       v2(1) = y_j;
01715 
01716       error =  theViewer.drawLine(v1, v2, 1.0, 1.0); 
01717         
01718       return error;
01719    
01720    }
01721    return 0;
01722 }
01723 
01724 Response*
01725 NLBeamColumn2d::setResponse(char **argv, int argc, Information &eleInformation)
01726 {
01727     //
01728     // we compare argv[0] for known response types 
01729     //
01730 
01731     // global force - 
01732     if (strcmp(argv[0],"forces") == 0 || strcmp(argv[0],"force") == 0
01733  || strcmp(argv[0],"globalForce") == 0 || strcmp(argv[0],"globalForces") == 0)
01734   return new ElementResponse(this, 1, P);
01735 
01736     // local force -
01737     else if (strcmp(argv[0],"localForce") == 0 || strcmp(argv[0],"localForces") == 0)
01738  return new ElementResponse(this, 2, P);
01739     
01740     // section response -
01741     else if (strcmp(argv[0],"section") ==0) {
01742   if (argc <= 2)
01743    return 0;
01744  
01745   int sectionNum = atoi(argv[1]);
01746   if (sectionNum > 0 && sectionNum <= nSections)
01747    return sections[sectionNum-1]->setResponse(&argv[2], argc-2, eleInformation);
01748   else
01749    return 0;
01750  }
01751     
01752  else
01753   return 0;
01754 }
01755 
01756 int 
01757 NLBeamColumn2d::getResponse(int responseID, Information &eleInfo)
01758 {
01759   static Vector force(6);
01760   double V;
01761 
01762   switch (responseID) {
01763     case 1:  // global forces
01764       return eleInfo.setVector(P);
01765 
01766     case 2:
01767       force(3) = Se(0);
01768       force(0) = -Se(0);
01769       force(2) = Se(1);
01770       force(5) = Se(2);
01771       V = (Se(1)+Se(2))/L;
01772       force(1) = V;
01773       force(4) = -V;
01774       return eleInfo.setVector(force);
01775       
01776     default: 
01777    return -1;
01778   }
01779 }
Copyright Contact Us