fElement.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.7 $
00022 // $Date: 2003/04/02 22:02:36 $
00023 // $Source: /usr/local/cvs/OpenSees/SRC/element/feap/fElement.cpp,v $
00024                                                                         
00025                                                                         
00026 // File: ~/element/fortran/fElement.C
00027 // 
00028 // Written: fmk 
00029 // Created: 07/98
00030 // Revision: A
00031 //
00032 // Description: This file contains the implementation for the fElement class.
00033 //
00034 // What: "@(#) fElement.C, revA"
00035 
00036 #include "fElement.h"
00037 #include <Domain.h>
00038 #include <Node.h>
00039 #include <Channel.h>
00040 #include <FEM_ObjectBroker.h>
00041 #include <UniaxialMaterial.h>
00042 #include <Renderer.h>
00043 
00044 #include <math.h>
00045 #include <stdlib.h>
00046 
00047 // initialise all class wise pointers to 0 and numfElements to 0
00048 Matrix **fElement::fElementM;
00049 Vector **fElement::fElementV;
00050 double *fElement::r;
00051 double *fElement::s;
00052 double *fElement::ul;
00053 double *fElement::xl;
00054 double *fElement::tl;
00055 int    *fElement::ix;
00056 int    fElement::numfElements(0);
00057 
00058 static double *work = 0;
00059 static int sizeWork = 0;
00060 
00061 #define MAX_NST 64
00062 
00063 // constructor:
00064 //  responsible for allocating the necessary space needed by each object
00065 //  and storing the tags of the fElement end nodes.
00066 fElement::fElement(int tag, 
00067                    int classTag,
00068                    int EleType,
00069                    int sizeD, int NEN,
00070                    int NDM, int NDF,
00071                    int numNh1, int numNh3)
00072 :Element(tag,classTag), nh1(numNh1), nh3(numNh3), h(0), eleType(EleType),
00073   theNodes(0), u(0), nen(NEN), ndf(NDF), ndm(NDM), d(0), data(0), 
00074  connectedNodes(0),nrCount(0), theLoad(0), Ki(0)
00075   
00076 {
00077     // allocate space for h array
00078     if (nh1 < 0) nh1 = 0;
00079     if (nh3 < 0) nh3 = 0;
00080     if (nh1 != 0 || nh3 != 0) {
00081         int sizeH = 2*nh1 + nh3;
00082         h = new double[sizeH];
00083         if (sizeWork < sizeH) {
00084           if (work != 0)
00085             delete [] work;
00086           work = new double[sizeH];
00087           if (work == 0) {
00088             opserr << "FATAL: fElement::fElement() - eleTag: " << tag;
00089             opserr << " ran out of memory creating h of size " << 2*nh1+nh3 << endln;
00090             exit(-1);
00091           }         
00092           sizeWork = sizeH;
00093         }
00094         if (h == 0 || work == 0) {
00095             opserr << "FATAL: fElement::fElement() - eleTag: " << tag;
00096             opserr << " ran out of memory creating h of size " << 2*nh1+nh3 << endln;
00097             exit(-1);
00098         }           
00099 
00100         for (int i=0; i<sizeH; i++) 
00101           h[i] = 0.0;
00102     }
00103 
00104     connectedNodes = new ID(NEN);
00105     d = new double[sizeD];
00106     for (int i=0; i<sizeD; i++) d[i] = 0.0;
00107     data = new Vector(d, sizeD);
00108 
00109     // allocate space for static varaibles on creation of first instance
00110     if (numfElements == 0) {
00111         fElementM = new Matrix *[MAX_NST+1];
00112         fElementV = new Vector *[MAX_NST+1];
00113         s = new double[(MAX_NST+1)*(MAX_NST+1)];
00114         r = new double[MAX_NST+1];
00115         ul = new double[(MAX_NST+1)*6];
00116         xl = new double[MAX_NST+1];
00117         tl = new double[MAX_NST+1];
00118         ix = new int[MAX_NST+1];        
00119 
00120         // check space was available -- otherwise exit
00121         if (fElementM == 0 || fElementV == 0 || ix == 0 ||
00122             r == 0 || s == 0 || ul == 0 || xl == 0 || tl == 0) {
00123 
00124             opserr << "FATAL: fElement::fElement() - eleTag: " << tag;
00125             opserr << " ran out of memory initialising static stuff\n";
00126             exit(-1);       
00127         }
00128         
00129         for (int i=0; i<MAX_NST+1; i++) {
00130             fElementM[i] = 0;
00131             fElementV[i] = 0;
00132         }
00133         fElementM[0] = new Matrix(1,1); // dummy for error
00134         fElementV[0] = new Vector(1);
00135     }
00136     
00137     // increment number of elements
00138     numfElements++;
00139 }
00140 
00141 
00142 fElement::fElement(int tag, 
00143                    int classTag,
00144                    int EleType,
00145                    int sizeD, int NEN,
00146                    int NDM, int NDF, int iow)
00147 :Element(tag,classTag), nh1(0), nh3(0), h(0), eleType(EleType),
00148   theNodes(0), u(0), nen(NEN), ndf(NDF), ndm(NDM), d(0), data(0), 
00149  connectedNodes(0), nrCount(0), theLoad(0), Ki(0)
00150 {
00151     connectedNodes = new ID(NEN);
00152     d = new double[sizeD];
00153     data = new Vector(d, sizeD);
00154     if (d == 0 || data == 0) {
00155         opserr << "FATAL: fElement::fElement() - eleTag: " << tag;
00156         opserr << " ran out of memory creating d of size " << sizeD << endln;
00157         exit(-1);
00158     }       
00159     for (int i=0; i<sizeD; i++) d[i] = 0.0;    
00160 
00161     // invoke the elmt() routine with isw == 1 to read in the element data
00162     // and create room for the h array stuff needed by the element
00163     this->invokefInit(1, iow); 
00164 
00165     // allocate space for h array
00166     if (nh1 < 0) nh1 = 0;
00167     if (nh3 < 0) nh3 = 0;
00168     if (nh1 != 0 || nh3 != 0) {
00169         int sizeH = 2*nh1+nh3;
00170         h = new double[sizeH];
00171         if (sizeWork < sizeH) {
00172           if (work != 0)
00173             delete [] work;
00174           work = new double[sizeH];
00175           if (work == 0) {
00176             opserr << "FATAL: fElement::fElement() - eleTag: " << tag;
00177             opserr << " ran out of memory creating h of size " << 2*nh1+nh3 << endln;
00178             exit(-1);
00179           }         
00180           sizeWork = sizeH;
00181         }
00182         if (h == 0 || work == 0) {
00183             opserr << "FATAL: fElement::fElement() - eleTag: " << this->getTag();
00184             opserr << " ran out of memory creating h of size " << sizeH << endln;
00185             exit(-1);
00186         }           
00187         else
00188             for (int i=0; i<sizeH; i++) h[i] = 0.0;
00189     }
00190 
00191     // allocate space for static varaibles on creation of first instance
00192     if (numfElements == 0) {
00193         fElementM = new Matrix *[MAX_NST+1];
00194         fElementV = new Vector *[MAX_NST+1];
00195         s = new double[(MAX_NST+1)*(MAX_NST+1)];
00196         r = new double[MAX_NST+1];
00197         ul = new double[(MAX_NST+1)*6];
00198         xl = new double[MAX_NST+1];
00199         tl = new double[MAX_NST+1];
00200         ix = new int[MAX_NST+1];        
00201 
00202         // check space was available -- otherwise exit
00203         if (fElementM == 0 || fElementV == 0 || ix == 0 ||
00204             r == 0 || s == 0 || ul == 0 || xl == 0 || tl == 0) {
00205 
00206             opserr << "FATAL: fElement::fElement() - eleTag: " << tag;
00207             opserr << " ran out of memory initialising static stuff\n";
00208             exit(-1);       
00209         }
00210         
00211         for (int i=0; i<MAX_NST+1; i++) {
00212             fElementM[i] = 0;
00213             fElementV[i] = 0;
00214         }
00215         fElementM[0] = new Matrix(1,1); // dummy for error
00216         fElementV[0] = new Vector(1);
00217     }
00218 
00219     // increment number of elements
00220     numfElements++;
00221 }
00222 
00223 // constructor:
00224 //   invoked by a FEM_ObjectBroker - blank object that recvSelf needs
00225 //   to be invoked upon
00226 fElement::fElement(int classTag)
00227 :Element(0, classTag), nh1(0), nh3(0), h(0),
00228  theNodes(0), u(0), nen(0), ndf(0), ndm(0), d(0), data(0), connectedNodes(0),
00229  theLoad(0), Ki(0)
00230 {
00231     // does nothing
00232 }
00233 
00234 //  destructor
00235 //     delete must be invoked on any objects created by the object
00236 //     and on the matertial object.
00237 fElement::~fElement()
00238 {
00239     // clear up any space allocated for individual object
00240 
00241     if (h != 0)
00242         delete [] h;
00243     if (u != 0)
00244         delete [] u;
00245     if (theNodes != 0)
00246         delete [] theNodes;
00247 
00248     if (data != 0)
00249         delete  data;
00250     if (connectedNodes != 0)
00251         delete  connectedNodes;
00252     if (d != 0)
00253         delete [] d;
00254     if (theLoad != 0)
00255       delete theLoad;
00256 
00257     if (Ki != 0)
00258       delete Ki;
00259 
00260     // if last element - clear up space allocated
00261 
00262     numfElements --;    
00263     if (numfElements == 0) {
00264         for (int i=0; i<MAX_NST+1; i++) {
00265             if (fElementM[i] != 0) delete fElementM[i];
00266             if (fElementV[i] != 0) delete fElementV[i];
00267         }
00268         delete [] fElementM;
00269         delete [] fElementV;
00270         delete [] s;
00271         delete [] r;
00272         delete [] ul;
00273         delete [] xl;
00274         delete [] tl;
00275         delete [] ix;   
00276     }
00277 }
00278 
00279 int
00280 fElement::getNumExternalNodes(void) const
00281 {
00282     return connectedNodes->Size();
00283 }
00284 
00285 const ID &
00286 fElement::getExternalNodes(void)
00287 {
00288     return *connectedNodes;
00289 }
00290 
00291 Node **
00292 fElement::getNodePtrs(void)
00293 {
00294     return theNodes;
00295 }
00296 
00297 int
00298 fElement::getNumDOF(void)
00299 {
00300     return ndf*nen;
00301 }
00302 
00303 void
00304 fElement::setDomain(Domain *theDomain)
00305 {
00306     // check Domain is not null - invoked when object removed from a domain
00307     if (theDomain == 0) {
00308         ndm = 0;
00309         nen = 0;
00310         ndf = 0;
00311         if (theNodes != 0) {
00312             delete [] theNodes;
00313             theNodes = 0;
00314         }
00315         return;
00316     }    
00317 
00318     // set up the pointers to the nodes
00319     const ID &theNodeTags = this->getExternalNodes();
00320 
00321     int numNodes = theNodeTags.Size();
00322     theNodes = new Node *[numNodes];
00323     for (int i=0; i<numNodes; i++) {
00324         Node *theNode = theDomain->getNode(theNodeTags(i));
00325         if (theNode == 0) {
00326             opserr << "WARNING fElement::setDomain(Domain *theDomain) - node: ";
00327             opserr << theNodeTags(i) << " does not exist in domain for ele " << *this;
00328             ndm = 0; nen = 0; ndf = 0;
00329             return;
00330         }
00331         // set up the pointer to the node
00332         theNodes[i] = theNode;
00333 
00334         
00335         // check the dimension and number of dof at the node 
00336         // is the same as all the other nodes of the element
00337         if (i == 0) {
00338             const Vector &crds = theNode->getCrds();
00339             ndm = crds.Size();                // ndm = dimesion of mesh
00340             ndf = theNode->getNumberDOF();    // ndf = number of dof at nodes
00341         } else {
00342             const Vector &crds = theNode->getCrds();    
00343             if (ndm != crds.Size()) {
00344                 opserr << "WARNING fElement::setDomain(Domain *theDomain) - node: ";
00345                 opserr << theNodeTags(i) << " not in correct dimension " << *this;
00346                 ndm = 0; nen = 0; ndf = 0;
00347                 return;         
00348             }
00349             if (ndf != theNode->getNumberDOF()) {
00350                 opserr << "WARNING fElement::setDomain(Domain *theDomain) - node: ";
00351                 opserr << theNodeTags(i) << " does not have correct #DOF " << *this;
00352                 ndm = 0; nen = 0; ndf = 0;
00353                 return;         
00354             }
00355         }
00356     }
00357 
00358     
00359     // call the DomainComponent class method THIS IS VERY IMPORTANT
00360     this->DomainComponent::setDomain(theDomain);
00361     
00362     // set nen - the number of element nodes
00363     nen = numNodes;
00364     
00365     // allocate memory for u
00366     int nst = ndf*nen;    
00367     u = new double[nst]; 
00368     if (u == 0) {
00369         opserr << "WARNING fElement::setDomain(Domain *theDomain) -  ";
00370         opserr << " ran out of memory creating u of size: " << nen*ndf << *this;
00371         ndm = 0; nen = 0; ndf = 0;
00372         return;                 
00373     }
00374     // zero u
00375     for (int ii=0; ii<nst; ii++) 
00376         u[ii] = 0.0;
00377 
00378 
00379     theLoad = new Vector(nst);
00380     if (theLoad == 0) {
00381       opserr << "Truss::setDomain - truss " << this->getTag() << 
00382         "out of memory creating vector of size" << nst << endln;
00383       exit(-1);
00384     }          
00385 
00386     // allocate the Matrix and Vector objects if none yet for this size nst
00387    if (fElementM[nst] == 0) {
00388        fElementM[nst] = new Matrix(s,nst,nst);
00389        fElementV[nst] = new Vector(r,nst);       
00390 
00391        if ((fElementM[nst] == 0) || (fElementV[nst] == 0)) {
00392            opserr << "WARNING fElement::setDomain(Domain *theDomain) -  ";
00393            opserr << " ran out of memory creating Matrix and Vector for " << *this;
00394            ndm = 0; nen = 0; ndf = 0;
00395            return;                      
00396        }
00397    }
00398 }
00399 
00400 
00401 int
00402 fElement::commitState()
00403 {
00404   int retVal = 0;
00405   // call element commitState to do any base class stuff
00406   if ((retVal = this->Element::commitState()) != 0) {
00407     opserr << "fElement::commitState () - failed in base class";
00408   }    
00409 
00410   if (nh1 != 0) 
00411     for (int i=0; i<nh1; i++)
00412       h[i] = h[i+nh1];
00413   
00414   nrCount = 0;
00415   return retVal;
00416 }
00417 
00418 int
00419 fElement::revertToLastCommit()
00420 {
00421     if (nh1 != 0) 
00422         for (int i=0; i<nh1; i++)
00423             h[i+nh1] = h[i];    
00424 
00425     nrCount = 0;
00426     return 0;
00427 }
00428 
00429 int
00430 fElement::revertToStart()
00431 {
00432     // does nothing
00433     return 0;
00434 }
00435 
00436 
00437 const Matrix &
00438 fElement::getTangentStiff(void)
00439 {
00440 
00441     // check for quick return
00442     if (nen == 0)
00443         return (*fElementM[0]);
00444     
00445     // get the current load factor
00446     Domain *theDomain=this->getDomain();
00447     double dm = theDomain->getCurrentTime();
00448     
00449     // set ctan, ior and iow
00450     double ctan[3];
00451     ctan[0] = 1.0; ctan[1] = 0.0; ctan[2] = 0.0;
00452     int ior = 0; int iow = 0;
00453     
00454     // call the ready routine to set ul, xl, tl and ix, NH1, NH2 and NH3
00455     int nstR = this->readyfRoutine(false);
00456 
00457     // zero the matrix
00458     fElementM[nstR]->Zero();    
00459     
00460     // invoke the fortran subroutine
00461     int isw = 3; 
00462     int nstI = this->invokefRoutine(ior, iow, ctan, isw);
00463     
00464     // check nst is as determined in readyfRoutine()
00465     if (nstI != nstR) {
00466         opserr << "FATAL fElement::getTangentStiff() problems with incompatable nst";
00467         opserr << " ready: " << nstR << " invoke: " << nstI << endln;
00468         exit(-1);
00469     }
00470 
00471     // return the matrix
00472 
00473     return *(fElementM[nstR]);
00474 
00475 }
00476 
00477 
00478 const Matrix &
00479 fElement::getDamp(void)
00480 {
00481     // check for quick return
00482     if (nen == 0)
00483         return (*fElementM[0]);
00484     
00485     // get the current load factor
00486     Domain *theDomain=this->getDomain();
00487     double dm = theDomain->getCurrentTime();
00488     
00489     // set ctan, ior and iow
00490     double ctan[3];
00491     ctan[0] = 0.0; ctan[1] = 1.0; ctan[2] = 0.0;
00492     int ior = 0; int iow = 0;
00493     
00494     // call the ready routine to set ul, xl, tl and ix, NH1, NH2 and NH3
00495     int NH1, NH2, NH3;    
00496     int nstR = this->readyfRoutine(true);
00497     
00498     // zero the matrix
00499     fElementM[nstR]->Zero();    
00500     
00501     // invoke the fortran subroutine
00502     int isw = 3; int nst = nen*ndf; int n = this->getTag();
00503 
00504 
00505     int nstI = this->invokefRoutine(ior, iow, ctan, isw);
00506     
00507     // check nst is as determined in readyfRoutine()
00508     if (nstI != nstR) {
00509         opserr << "FATAL fElement::getTangentStiff() problems with incompatable nst";
00510         opserr << " ready: " << nstR << " invoke: " << nstI << endln;
00511         exit(-1);
00512     }
00513     
00514     // return the matrix
00515     return *(fElementM[nstR]);
00516 }
00517 
00518 
00519 const Matrix &
00520 fElement::getMass(void)
00521 {
00522     // check for quick return
00523     if (nen == 0)
00524         return (*fElementM[0]);
00525     
00526     // get the current load factor
00527     Domain *theDomain=this->getDomain();
00528     double dm = theDomain->getCurrentTime();
00529     
00530     // set ctan, ior and iow
00531     double ctan[3];
00532     ctan[0] = 0.0; ctan[1] = 0.0; ctan[2] = 1.0;
00533     int ior = 0; int iow = 0;
00534     
00535     // call the ready routine to set ul, xl, tl and ix, NH1, NH2 and NH3
00536     int NH1, NH2, NH3;    
00537     int nstR = this->readyfRoutine(true);
00538     
00539     // zero the matrix and vector (consistant and lumped)
00540     fElementM[nstR]->Zero();    
00541     fElementV[nstR]->Zero();        
00542     
00543     // invoke the fortran subroutine
00544     int isw = 5; int nst = nen*ndf; int n = this->getTag();
00545     int nstI = this->invokefRoutine(ior, iow, ctan, isw);
00546     
00547     // check nst is as determined in readyfRoutine()
00548     if (nstI != nstR) {
00549         opserr << "FATAL fElement::getTangentStiff() problems with incompatable nst";
00550         opserr << " ready: " << nstR << " invoke: " << nstI << endln;
00551         exit(-1);
00552     }
00553     
00554     // return the matrix
00555     return *(fElementM[nstR]);
00556 }
00557 
00558 
00559 
00560 void 
00561 fElement::zeroLoad(void)
00562 {
00563   // does nothing now
00564   if (theLoad != 0)
00565     theLoad->Zero();
00566 }
00567 
00568 int
00569 fElement::addLoad(ElementalLoad *theLoad, double loadFactor)
00570 {
00571   opserr <<"fElement::addLoad - load type unknown for truss with tag: " << this->getTag() << endln;
00572   return -1;
00573 }
00574 
00575 
00576 
00577 int 
00578 fElement::addInertiaLoadToUnbalance(const Vector &accel)
00579 {
00580   const Matrix &mass = this->getMass();
00581   int nstR = nen*ndf;
00582   Vector &resid = *(fElementV[nstR]);    
00583   static const int numberNodes = 4 ;
00584 
00585   // store computed RV fro nodes in resid vector
00586   int count = 0;
00587   for (int i=0; i<nen; i++) {
00588     const Vector &Raccel = theNodes[i]->getRV(accel);
00589     for (int j=0; j<ndf; j++)
00590       resid(count++) = Raccel(i);
00591   }
00592 
00593   // create the load vector if one does not exist
00594   if (theLoad == 0) 
00595     theLoad = new Vector(nstR);
00596 
00597   // add -M * RV(accel) to the load vector
00598   theLoad->addMatrixVector(1.0, mass, resid, -1.0);
00599 
00600   
00601   return 0;
00602 }
00603 
00604 
00605 const Vector &
00606 fElement::getResistingForce()
00607 {               
00608     // check for quick return
00609     if (nen == 0)
00610         return (*fElementV[0]);
00611     
00612     // get the current load factor
00613     Domain *theDomain=this->getDomain();
00614     double dm = theDomain->getCurrentTime();
00615     
00616     // set ctan, ior and iow
00617     double ctan[3];
00618     ctan[0] = 0.0; ctan[1] = 0.0; ctan[2] = 0.0;
00619     int ior = 0; int iow = 0;
00620     
00621     // call the ready routine to set ul, xl, tl and ix, NH1, NH2 and NH3
00622     int NH1, NH2, NH3;    
00623     int nstR = this->readyfRoutine(false);
00624 
00625     // zero the vector
00626     fElementV[nstR]->Zero();        
00627     
00628     // invoke the fortran subroutine
00629     int isw = 6; int nst = nen*ndf; int n = this->getTag();
00630     int nstI = this->invokefRoutine(ior, iow, ctan, isw);
00631     
00632     // check nst is as determined in readyfRoutine()
00633     if (nstI != nstR) {
00634         opserr << "FATAL fElement::getTangentStiff() problems with incompatable nst";
00635         opserr << " ready: " << nstR << " invoke: " << nstI << endln;
00636         exit(-1);
00637     }
00638 
00639     // negate the sign of the loads -- feap elements return -ku
00640     (*fElementV[nstR]) *= -1.0;
00641     
00642     // add the applied loads from other sources
00643     (*fElementV[nstR]) -= *theLoad;
00644     
00645     // return the matrix
00646     return *(fElementV[nstR]);    
00647 }
00648 
00649 
00650 const Vector &
00651 fElement::getResistingForceIncInertia()
00652 {       
00653     // check for quick return
00654     if (nen == 0)
00655         return (*fElementV[0]);
00656     
00657     // get the current load factor
00658     Domain *theDomain=this->getDomain();
00659     double dm = theDomain->getCurrentTime();
00660     
00661     // set ctan, ior and iow
00662     double ctan[3];
00663     ctan[0] = 0.0; ctan[1] = 0.0; ctan[2] = 0.0;
00664     int ior = 0; int iow = 0;
00665     
00666     // call the ready routine to set ul, xl, tl and ix, NH1, NH2 and NH3
00667     int NH1, NH2, NH3;    
00668     int nstR = this->readyfRoutine(true);
00669 
00670     // zero the vector
00671     fElementV[nstR]->Zero();        
00672     
00673     // invoke the fortran subroutine
00674     int isw = 6; int nst = nen*ndf; int n = this->getTag();
00675     int nstI = this->invokefRoutine(ior, iow, ctan, isw);
00676     
00677     // check nst is as determined in readyfRoutine()
00678     if (nstI != nstR) {
00679         opserr << "FATAL fElement::getTangentStiff() problems with incompatable nst";
00680         opserr << " ready: " << nstR << " invoke: " << nstI << endln;
00681         exit(-1);
00682     }
00683 
00684     // negate the sign of the loads -- feap elements return -ku
00685     (*fElementV[nstR]) *= -1.0;
00686     
00687     // return the matrix
00688     return *(fElementV[nstR]);    
00689 }
00690 
00691 
00692 int
00693 fElement::sendSelf(int commitTag, Channel &theChannel)
00694 {
00695   opserr << "fElement::sendSelf() - not yet implemented\n";
00696   return -1;
00697 }
00698 
00699 int
00700 fElement::recvSelf(int commitTag, Channel &theChannel, FEM_ObjectBroker &theBroker)
00701 {
00702   opserr << "fElement::recvSelf() - not yet implemented\n";
00703   return -1;
00704 }
00705 
00706 
00707 int
00708 fElement::displaySelf(Renderer &theViewer, int displayMode, float fact)
00709 {
00710     return 0;
00711 }
00712 
00713 
00714 void
00715 fElement::Print(OPS_Stream &s, int flag)
00716 {
00717     int ior = 0; int iow = 1;    
00718     ior = -1;
00719 
00720     s << "fElement::Print() - can only print to cerr at present\n";
00721     ior = -1;
00722 
00723     // get the current load factor
00724     Domain *theDomain=this->getDomain();
00725     double dm = theDomain->getCurrentTime();
00726     
00727     // set ctan, ior and iow
00728     double ctan[3];
00729     ctan[0] = 0.0; ctan[1] = 0.0; ctan[2] = 0.0;
00730 
00731     
00732     // call the ready routine to set ul, xl, tl and ix, NH1, NH2 and NH3
00733     int NH1, NH2, NH3;    
00734     int nstR = this->readyfRoutine(false);
00735 
00736     // invoke the fortran subroutine
00737     int isw = 4; int nst = nen*ndf; int n = this->getTag();
00738     int nstI = this->invokefRoutine(ior, iow, ctan, isw);
00739 }
00740 
00741 #ifdef _WIN32
00742 
00743 extern "C" int GETCOMMON(int *mynh1, int *mynh3, int *sizeH, 
00744                                   double *myh);
00745 
00746 
00747 extern "C" int FILLCOMMON(int *mynen, double *mydm, int *myn, 
00748                                    int *myior, int *myiow, int *mynh1, 
00749                                    int *mynh2, int *mynh3, int *sumnh, 
00750                                    double *myh, double *myctan,
00751                                    int *nrCount);
00752 
00753 extern "C" int ELMT01(double *d, double *ul, double *xl, int *ix, 
00754                                double *tl, double *s, double *r, int *ndf, 
00755                                int *ndm, int *nst, int *isw);
00756 
00757 extern "C" int ELMT02(double *d, double *ul, double *xl, int *ix, 
00758                                double *tl, double *s, double *r, int *ndf, 
00759                                int *ndm, int *nst, int *isw);
00760                        
00761 extern "C" int ELMT03(double *d, double *ul, double *xl, int *ix, 
00762                                double *tl, double *s, double *r, int *ndf, 
00763                                int *ndm, int *nst, int *isw);
00764                        
00765 extern "C" int ELMT04(double *d, double *ul, double *xl, int *ix, 
00766                                double *tl, double *s, double *r, int *ndf, 
00767                                int *ndm, int *nst, int *isw);
00768                        
00769 extern "C" int ELMT05(double *d, double *ul, double *xl, int *ix, 
00770                                double *tl, double *s, double *r, int *ndf, 
00771                                int *ndm, int *nst, int *isw);                  
00772 
00773 #define getcommon_      GETCOMMON
00774 #define fillcommon_     FILLCOMMON
00775 #define elmt01_         ELMT01
00776 #define elmt02_         ELMT02
00777 #define elmt03_         ELMT03
00778 #define elmt04_         ELMT03
00779 #define elmt05_         ELMT05
00780 
00781 #else
00782 extern "C" int getcommon_(int *mynh1, int *mynh3, int *sizeH, double *myh);
00783 
00784 
00785 extern "C" int fillcommon_(int *mynen, double *mydm, int *myn, int *myior, 
00786                            int *myiow, int *mynh1, int *mynh2, int *mynh3,
00787                            int *sumnh, double *myh, double *myctan,
00788                            int *nrCount);
00789 
00790 extern "C" int elmt01_(double *d, double *ul, double *xl, int *ix, double *tl, 
00791                        double *s, double *r, int *ndf, int *ndm, int *nst, 
00792                        int *isw);
00793 
00794 extern "C" int elmt02_(double *d, double *ul, double *xl, int *ix, double *tl, 
00795                        double *s, double *r, int *ndf, int *ndm, int *nst, 
00796                        int *isw);
00797                        
00798 extern "C" int elmt03_(double *d, double *ul, double *xl, int *ix, double *tl, 
00799                        double *s, double *r, int *ndf, int *ndm, int *nst, 
00800                        int *isw);
00801                        
00802 extern "C" int elmt04_(double *d, double *ul, double *xl, int *ix, double *tl, 
00803                        double *s, double *r, int *ndf, int *ndm, int *nst, 
00804                        int *isw);
00805                        
00806 extern "C" int elmt05_(double *d, double *ul, double *xl, int *ix, double *tl, 
00807                        double *s, double *r, int *ndf, int *ndm, int *nst, 
00808                        int *isw); 
00809 #endif         
00810 
00811 int
00812 fElement::invokefRoutine(int ior, int iow, double *ctan, int isw)
00813 {
00814     // fill the common blocks
00815     // determine position in h of nh1, nh2 and nh3 - remember Fortarn indexing
00816     int NH1, NH2, NH3;
00817     if (nh1 != 0) { 
00818         NH1 = 1; 
00819         NH2 = nh1 + NH1; 
00820         NH3 = nh1 + NH2; 
00821     } else {
00822         NH1 = 1;
00823         NH2 = 1;
00824         NH3 = 1;
00825     }
00826     
00827     int NDM = ndm;
00828     int NDF = ndf;
00829     
00830     int n = this->getTag();
00831     int sum = 2*nh1 + nh3;    
00832     int count = nrCount;
00833 
00834 
00835     double dm = 0.0; // load factor
00836 
00837     fillcommon_(&nen, &dm, &n, &ior, &iow, &NH1, &NH2, &NH3, &sum, 
00838                 h, ctan, &count);
00839 
00840     // invoke the fortran subroutine
00841 
00842     int nst = nen*ndf;
00843     if (nst != 0) {
00844         if (eleType == 1)
00845             elmt01_(d,ul,xl,ix,tl,s,r,&NDF,&NDM,&nst,&isw);
00846         else if (eleType == 2)
00847             elmt02_(d,ul,xl,ix,tl,s,r,&NDF,&NDM,&nst,&isw);         
00848         else if (eleType == 3)
00849             elmt03_(d,ul,xl,ix,tl,s,r,&NDF,&NDM,&nst,&isw);         
00850         else if (eleType == 4)
00851             elmt04_(d,ul,xl,ix,tl,s,r,&NDF,&NDM,&nst,&isw);         
00852         else if (eleType == 5) 
00853             elmt05_(d,ul,xl,ix,tl,s,r,&ndf,&NDM,&nst,&isw);         
00854         else {
00855             opserr << "fElement::invokefRoutine() unknown element type ";
00856             opserr << eleType << endln;
00857         }
00858         
00859         // now copy the stuff from common block to h array
00860         getcommon_(&NH1,&NH3,&sum,h);
00861     }
00862 
00863     return nst;
00864 }
00865 
00866 
00867 int
00868 fElement::invokefInit(int isw, int iow)
00869 {
00870     // fill the common blocks
00871     // determine position in h of nh1, nh2 and nh3 - remember Fortarn indexing
00872     int NH1 =0;
00873     int NH2 =0;
00874     int NH3 =0;
00875 
00876     int NDM = ndm;
00877     int NDF = ndf;   
00878     double ctan[3];    
00879 
00880     int n = this->getTag();
00881     int sum = 0;    
00882     int ior = 0;
00883     int count = nrCount;
00884 
00885     double dm = 0.0;
00886     
00887     fillcommon_(&nen, &dm, &n, &ior, &iow, &NH1, &NH2, &NH3, &sum, 
00888                 h, ctan, &count);
00889 
00890     // invoke the fortran subroutine
00891 
00892     int nst = nen*ndf;
00893     if (nst != 0) {
00894         if (eleType == 1)
00895             elmt01_(d,ul,xl,ix,tl,s,r,&NDF,&NDM,&nst,&isw);
00896         else if (eleType == 2)
00897             elmt02_(d,ul,xl,ix,tl,s,r,&NDF,&NDM,&nst,&isw);         
00898         else if (eleType == 3)
00899             elmt03_(d,ul,xl,ix,tl,s,r,&NDF,&NDM,&nst,&isw);         
00900         else if (eleType == 4)
00901             elmt04_(d,ul,xl,ix,tl,s,r,&NDF,&NDM,&nst,&isw);         
00902         else if (eleType == 5)
00903             elmt05_(d,ul,xl,ix,tl,s,r,&NDF,&NDM,&nst,&isw);         
00904         else {
00905             opserr << "fElement::invokefRoutine() unknown element type ";
00906             opserr << eleType << endln;
00907         }
00908 
00909         if (nst < 0) {
00910             opserr << "FATAL: fElement::fElement() - eleTag: " << this->getTag();
00911             opserr << " ran out of memory creating h of size " << nst << endln;
00912             exit(-1);
00913         }
00914     }
00915 
00916     // now get the size of the state info needed by the element
00917     sum = 0;
00918     getcommon_(&NH1,&NH3,&sum,h);
00919     nh1 = NH1; nh3=NH3;
00920         return 0;
00921 }
00922 
00923 int
00924 fElement::readyfRoutine(bool incInertia)
00925 {
00926     // determine nst 
00927     int nst = ndf*nen;
00928 
00929     // loop over nodes - fill in xl, ul, ix as we go
00930     int posUl = 0;
00931     int posXl = 0;
00932     for (int j=0; j<nen; j++) {
00933         Node *theNode = theNodes[j];
00934 
00935         // add the node tag to ix
00936         ix[j] = theNode->getTag();
00937         
00938         // add displacement, velocity, accel and  increments to ul
00939         // Note: we get nodal vel and accel only if inertia is true, this
00940         // will save memory in static analysis -- look at Node implementation   
00941         const Vector &trialDisp = theNode->getTrialDisp();
00942         const Vector &commitDisp = theNode->getDisp();        
00943         const Vector &crd = theNode->getCrds();
00944 
00945         // add the coordinates to xl            
00946         int crdSize = crd.Size();
00947 
00948         for (int i=0; i<crdSize; i++) {
00949             xl[posXl] = crd(i);     
00950             posXl++;
00951         }
00952         
00953         if (incInertia == true) { 
00954             const Vector &trialVel = theNode->getTrialVel();
00955             const Vector &trialAccel = theNode->getTrialAccel();
00956             const Vector &commitVel = theNode->getVel();        
00957             for (int i=0; i<trialDisp.Size(); i++) {
00958                 double trialDispI = trialDisp(i);
00959                 ul[posUl] = trialDispI;
00960                 ul[posUl+nst] = trialDispI - commitDisp(i);
00961                 ul[posUl+2*nst] = trialDispI - u[posUl];                    
00962                 ul[posUl+3*nst] = trialVel(i);
00963                 ul[posUl+4*nst] = trialAccel(i);            
00964                 ul[posUl+5*nst] = commitVel(i);                         
00965                 u[posUl] = trialDispI; // u(k-1) on next call
00966                 posUl++;                                    
00967             }
00968         } else {
00969             for (int i=0; i<trialDisp.Size(); i++) {
00970                 double trialDispI = trialDisp(i);
00971                 ul[posUl] = trialDispI;
00972                 ul[posUl+nst] = trialDispI - commitDisp(i);
00973                 ul[posUl+2*nst] = trialDispI - u[posUl];                    
00974                 ul[posUl+3*nst] = 0.0;
00975                 ul[posUl+4*nst] = 0.0;      
00976                 ul[posUl+5*nst] = 0.0;              
00977                 u[posUl] = trialDispI;      
00978                 posUl++;
00979             }
00980         }
00981     }
00982 
00983     // check we have a matrix and vector created for an object of this size
00984     if (fElementM[nst] == 0) {
00985         fElementM[nst] = new Matrix(s,nst,nst);
00986         fElementV[nst] = new Vector(r,nst);
00987     
00988         if (fElementM[nst] == 0 || fElementV[nst] == 0) {
00989             opserr << "FATAL fElement::getTangentStiff() nst: " << nst;
00990             opserr << "ran out of memory\n";
00991             exit(-1);
00992         }  
00993     }
00994     return nst;
00995 }
00996 
00997 
00998 
00999 int
01000 fElement::update()
01001 {
01002     // determine nst 
01003     int nst = ndf*nen;
01004 
01005     // increment the newton-raphson count -- needed for Prof. Fillipou's element
01006     nrCount++;
01007     
01008     return 0;
01009 }
01010 
01011 
01012 const Matrix &
01013 fElement::getInitialStiff(void)
01014 {
01015   if (Ki == 0)
01016     Ki = new Matrix(this->getTangentStiff());
01017 
01018   if (Ki == 0) {
01019     opserr << "FATAL fElement::getInitialStiff() -";
01020     opserr << "ran out of memory\n";
01021     exit(-1);
01022   }  
01023     
01024   return *Ki;
01025 }
01026 
01027 
01028 
01029 

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