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

FE_Element.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.3 $
00022 // $Date: 2001/03/31 14:58:49 $
00023 // $Source: /usr/local/cvs/OpenSees/SRC/analysis/fe_ele/FE_Element.cpp,v $
00024                                                                         
00025                                                                         
00026 // File: ~/analysis/FE_Element.C
00027 //
00028 // Written: fmk 
00029 
00030 // Created: 11/96
00031 // Revision: A
00032 //
00033 // Purpose: This file contains the code for implementing the methods
00034 // of the FE_Element class interface.
00035 
00036 #include <FE_Element.h>
00037 #include <stdlib.h>
00038 
00039 #include <Element.h>
00040 #include <Domain.h>
00041 #include <Node.h>
00042 #include <DOF_Group.h>
00043 #include <Integrator.h>
00044 #include <Subdomain.h>
00045 #include <AnalysisModel.h>
00046 #include <Matrix.h>
00047 #include <Vector.h>
00048 
00049 #define MAX_NUM_DOF 64
00050 
00051 // static variables initialisation
00052 Matrix FE_Element::errMatrix(1,1);
00053 Vector FE_Element::errVector(1);
00054 Matrix **FE_Element::theMatrices; // pointers to class wide matrices
00055 Vector **FE_Element::theVectors;  // pointers to class widde vectors
00056 int FE_Element::numFEs(0);           // number of objects
00057 
00058 //  FE_Element(Element *, Integrator *theIntegrator);
00059 // construictor that take the corresponding model element.
00060 FE_Element::FE_Element(Element *ele)
00061 :myDOF_Groups((ele->getExternalNodes()).Size()), myID(ele->getNumDOF()), 
00062  numDOF(ele->getNumDOF()), theModel(0), myEle(ele), 
00063  theResidual(0), theTangent(0), theIntegrator(0), Kc(0)
00064 {
00065     if (numDOF <= 0) {
00066  cerr << "FE_Element::FE_Element(Element *) ";
00067  cerr << " element must have 1 dof " << *ele;
00068  exit(-1);
00069     }
00070     
00071     // get elements domain & check it is valid
00072     Domain *theDomain = ele->getDomain();
00073     if (theDomain == 0) {
00074  cerr << "FATAL FE_Element::FE_Element() - element has no domain "<< *ele;
00075  exit(-1);
00076     }
00077 
00078     // keep a pointer to all DOF_Groups
00079     int numGroups = ele->getNumExternalNodes();
00080     const ID &nodes = ele->getExternalNodes();
00081 
00082     for (int i=0; i<numGroups; i++) {
00083  Node *nodePtr =theDomain->getNode(nodes(i));
00084  if (nodePtr == 0) {
00085      cerr << "FATAL FE_Element::FE_Element() - Node: ";
00086      cerr <<  nodes(i) <<  "does not exist in the Domain\n";
00087      exit(-1);
00088  }
00089  
00090  DOF_Group *dofGrpPtr = nodePtr->getDOF_GroupPtr();
00091  if (dofGrpPtr != 0) 
00092      myDOF_Groups(i) = dofGrpPtr->getTag(); 
00093  else {
00094      cerr << "FATAL FE_Element::FE_Element() - Node: ";
00095      cerr <<  *nodePtr <<  " has no DOF_Group associated with it\n";
00096      exit(-1);
00097  }
00098     }
00099 
00100     // if this is the first FE_Element we now
00101     // create the arrays used to store pointers to class wide
00102     // matrix and vector objects used to return tangent and residual
00103     if (numFEs == 0) {
00104  theMatrices = new Matrix *[MAX_NUM_DOF+1];
00105  theVectors  = new Vector *[MAX_NUM_DOF+1];
00106  
00107  if (theMatrices == 0 || theVectors == 0) {
00108      cerr << "FE_Element::FE_Element(Element *) ";
00109      cerr << " ran out of memory";     
00110  }
00111  for (int i=0; i<MAX_NUM_DOF; i++) {
00112      theMatrices[i] = 0;
00113      theVectors[i] = 0;
00114  }
00115     }
00116 
00117     if (ele->isSubdomain() == false) {
00118  
00119  // if Elements are not subdomains, set up pointers to
00120  // objects to return tangent Matrix and residual Vector.
00121 
00122  if (numDOF <= MAX_NUM_DOF) {
00123      // use class wide objects
00124      if (theVectors[numDOF] == 0) {
00125   theVectors[numDOF] = new Vector(numDOF);
00126   theMatrices[numDOF] = new Matrix(numDOF,numDOF);
00127   theResidual = theVectors[numDOF];
00128   theTangent = theMatrices[numDOF];
00129   if (theResidual == 0 || theResidual->Size() != numDOF || 
00130       theTangent == 0 || theTangent->noCols() != numDOF) {  
00131       cerr << "FE_Element::FE_Element(Element *) ";
00132       cerr << " ran out of memory for vector/Matrix of size :";
00133       cerr << numDOF << endl;
00134       exit(-1);
00135   }
00136      } else {
00137   theResidual = theVectors[numDOF];
00138   theTangent = theMatrices[numDOF];
00139      }
00140  } else {
00141      // create matrices and vectors for each object instance
00142      theResidual = new Vector(numDOF);
00143      theTangent = new Matrix(numDOF, numDOF);
00144      if (theResidual == 0 || theTangent ==0 ||
00145   theTangent ==0 || theTangent->noRows() ==0) {
00146      
00147   cerr << "FE_Element::FE_Element(Element *) ";
00148   cerr << " ran out of memory for vector/Matrix of size :";
00149   cerr << numDOF << endl;
00150   exit(-1);
00151      }
00152  } 
00153     } else {
00154 
00155  // as subdomains have own matrix for tangent and residual don't need
00156  // to set matrix and vector pointers to these objects
00157         theResidual = new Vector(numDOF); 
00158   // invoke setFE_ElementPtr() method on Subdomain
00159  Subdomain *theSub = (Subdomain *)ele;
00160  theSub->setFE_ElementPtr(this);
00161     }
00162  
00163     // increment number of FE_Elements by 1
00164     numFEs++;
00165 }
00166 
00167 
00168 FE_Element::FE_Element(int numDOF_Group, int ndof)
00169 :myDOF_Groups(numDOF_Group), myID(ndof), numDOF(ndof), theModel(0),
00170  myEle(0), theResidual(0), theTangent(0), theIntegrator(0), Kc(0)
00171 {
00172     // this is for a subtype, the subtype must set the myDOF_Groups ID array
00173     numFEs++;
00174 
00175     // if this is the first FE_Element we now
00176     // create the arrays used to store pointers to class wide
00177     // matrix and vector objects used to return tangent and residual
00178     if (numFEs == 0) {
00179  theMatrices = new Matrix *[MAX_NUM_DOF+1];
00180  theVectors  = new Vector *[MAX_NUM_DOF+1];
00181  
00182  if (theMatrices == 0 || theVectors == 0) {
00183      cerr << "FE_Element::FE_Element(Element *) ";
00184      cerr << " ran out of memory";     
00185  }
00186  for (int i=0; i<MAX_NUM_DOF; i++) {
00187      theMatrices[i] = 0;
00188      theVectors[i] = 0;
00189  }
00190     }
00191     
00192     // as subtypes have no access to the tangent or residual we don't set them
00193     // this way we can detect if subclass does not provide all methods it should
00194 }
00195 
00196 
00197 
00198 // ~FE_Element();    
00199 // destructor.
00200 FE_Element::~FE_Element()
00201 {
00202     // decrement number of FE_Elements
00203     numFEs--;
00204 
00205     // delete tangent and residual if created specially
00206     if (numDOF > MAX_NUM_DOF) {
00207  if (theTangent != 0) delete theTangent;
00208  if (theResidual != 0) delete theResidual;
00209  if (Kc != 0) delete Kc;
00210     }
00211 
00212     // if this is the last FE_Element, clean up the
00213     // storage for the matrix and vector objects
00214     if (numFEs == 0) {
00215  for (int i=0; i<MAX_NUM_DOF; i++) {
00216      if (theVectors[i] != 0)
00217   delete theVectors[i];
00218      if (theMatrices[i] != 0)
00219   delete theMatrices[i];
00220  } 
00221  delete [] theMatrices;
00222  delete [] theVectors;
00223     }
00224 }    
00225 
00226 
00227 const ID &
00228 FE_Element::getDOFtags(void) const 
00229 {
00230     return myDOF_Groups;
00231 }
00232 
00233 
00234 // const ID &getID(void) const;
00235 // Method to return the current ID.
00236 
00237 const ID &
00238 FE_Element::getID(void) const
00239 {
00240     return myID;
00241 }
00242 
00243 void 
00244 FE_Element::setAnalysisModel(AnalysisModel &theAnalysisModel)
00245 {
00246     theModel = &theAnalysisModel;
00247 }
00248 
00249 // void setID(int index, int value);
00250 // Method to set the corresponding index of the ID to value.
00251 
00252 int
00253 FE_Element::setID(void)
00254 {
00255     int current = 0;
00256     
00257     if (theModel == 0) {
00258  cerr << "WARNING FE_Element::setID() - no AnalysisModel set\n";
00259  return -1;
00260     }
00261     
00262     int numGrps = myDOF_Groups.Size();
00263     for (int i=0; i<numGrps; i++) {
00264  int tag = myDOF_Groups(i);
00265 
00266  DOF_Group *dofPtr = theModel->getDOF_GroupPtr(tag);
00267  if (dofPtr == 0) {
00268      cerr << "WARNING FE_Element::setID: 0 DOF_Group Pointer\n";
00269      return -2;
00270  }
00271      
00272  const ID &theDOFid = dofPtr->getID();
00273 
00274  for (int j=0; j<theDOFid.Size(); j++)  
00275      if (current < numDOF)
00276   myID(current++) = theDOFid(j);
00277      else {
00278   cerr << "WARNING FE_Element::setID() - numDOF and";
00279   cerr << " number of dof at the DOF_Groups\n";
00280   return -3;
00281      }  
00282     }
00283     return 0;
00284 }
00285 
00286 
00287 const Matrix &
00288 FE_Element::getTangent(Integrator *theNewIntegrator)
00289 {
00290     theIntegrator = theNewIntegrator;
00291     
00292     if (myEle == 0) {
00293  cerr << "FATAL FE_Element::getTangent() - no Element *given ";
00294  cerr << "- subclasses must provide implementation - ";
00295  cerr << " - a 1x1 error matrix will be returned.\n";
00296  exit(-1);
00297     }
00298 
00299 
00300     if (myEle->isSubdomain() == false) {
00301       theNewIntegrator->formEleTangent(this);          
00302       return *theTangent;
00303     } else {
00304       Subdomain *theSub = (Subdomain *)myEle;
00305       theSub->computeTang();     
00306       return theSub->getTang();
00307     }
00308 }
00309 
00310 const Vector &
00311 FE_Element::getResidual(Integrator *theNewIntegrator)
00312 {
00313     theIntegrator = theNewIntegrator;
00314 
00315     if (theIntegrator == 0)
00316       return *theResidual;
00317 
00318     if (myEle == 0) {
00319  cerr << "FATAL FE_Element::getTangent() - no Element *given ";
00320  cerr << "- subclasses must provide implementation - ";
00321  cerr << " - an error Vector of order 1 will be returned.\n";
00322  exit(-1);
00323     }    
00324 
00325     if (myEle->isSubdomain() == false) {
00326       theNewIntegrator->formEleResidual(this);
00327       return *theResidual;
00328     } else {
00329       Subdomain *theSub = (Subdomain *)myEle;
00330       theSub->computeResidual();     
00331       return theSub->getResistingForce();
00332     }
00333 }
00334 
00335 
00336 
00337 void  
00338 FE_Element::zeroTangent(void)
00339 {
00340     if (myEle != 0) {
00341  if (myEle->isSubdomain() == false)
00342      theTangent->Zero();
00343  else {
00344      cerr << "WARNING FE_Element::zeroTangent() - ";
00345      cerr << "- this should not be called on a Subdomain!\n";
00346  }              
00347     }
00348     else {
00349  cerr << "WARNING FE_Element::zeroTangent() - no Element *given ";
00350  cerr << "- subclasses must provide implementation\n";
00351     }
00352 }
00353 
00354 void  
00355 FE_Element::addKtToTang(double fact)
00356 {
00357     if (myEle != 0) {
00358  
00359  // check for a quick return 
00360  if (fact == 0.0) 
00361      return;
00362  else if (myEle->isSubdomain() == false)     
00363      theTangent->addMatrix(1.0, myEle->getTangentStiff(),fact);
00364  else {
00365      cerr << "WARNING FE_Element::addKToTang() - ";
00366      cerr << "- this should not be called on a Subdomain!\n";
00367  }              
00368     }
00369     else {
00370  cerr << "WARNING FE_Element::addKToTang() - no Element *given ";
00371  cerr << "- subclasses must provide implementation\n";
00372     }         
00373 }
00374 
00375 void  
00376 FE_Element::addKsToTang(double fact)
00377 {
00378     if (myEle != 0) {
00379  
00380  // check for a quick return 
00381  if (fact == 0.0) 
00382      return;
00383  else if (myEle->isSubdomain() == false)     
00384      theTangent->addMatrix(1.0, myEle->getSecantStiff(),fact);
00385  else {
00386      cerr << "WARNING FE_Element::addKToTang() - ";
00387      cerr << "- this should not be called on a Subdomain!\n";
00388  }              
00389     }
00390     else {
00391  cerr << "WARNING FE_Element::addKToTang() - no Element *given ";
00392  cerr << "- subclasses must provide implementation\n";
00393     }         
00394 }
00395 
00396 void  
00397 FE_Element::addCtoTang(double fact)
00398 {
00399     if (myEle != 0) {
00400  
00401  // check for a quick return 
00402  if (fact == 0.0) 
00403      return;
00404  else if (myEle->isSubdomain() == false)          
00405   theTangent->addMatrix(1.0, myEle->getDamp(),fact);
00406  else {
00407      cerr << "WARNING FE_Element::addCToTang() - ";
00408      cerr << "- this should not be called on a Subdomain!\n";
00409  }               
00410     }
00411     else {
00412  cerr << "WARNING FE_Element::addCToTang() - no Element *given ";
00413  cerr << "- subclasses must provide implementation\n";
00414     }             
00415 }
00416     
00417 void  
00418 FE_Element::addMtoTang(double fact)
00419 {
00420     if (myEle != 0) {
00421 
00422  // check for a quick return 
00423  if (fact == 0.0) 
00424      return;
00425  else if (myEle->isSubdomain() == false)          
00426   theTangent->addMatrix(1.0, myEle->getMass(),fact);
00427  else {
00428      cerr << "WARNING FE_Element::addMToTang() - ";
00429      cerr << "- this should not be called on a Subdomain!\n";
00430  }               
00431     } 
00432     else {
00433  cerr << "WARNING FE_Element::addMToTang() - no Element *given ";
00434  cerr << "- subclasses must provide implementation\n";
00435     }             
00436 }    
00437 
00438 int
00439 FE_Element::setKc(void) 
00440 {
00441   if (myEle != 0) {
00442     
00443     if (Kc == 0) {
00444       Kc = new Matrix(myEle->getTangentStiff());
00445       if (Kc == 0 || Kc->noCols() == 0) {
00446  cerr << "WARNING FE_Element::setKc() - out of memory";
00447  return -1;
00448       }
00449     } else
00450       (*Kc) = myEle->getTangentStiff();
00451   }
00452 
00453   return 0;
00454 }
00455 
00456 void  
00457 FE_Element::addKcToTang(double fact)
00458 {
00459   if (myEle != 0) {
00460 
00461     if (Kc != 0) {
00462 
00463       // check for a quick return 
00464       if (fact == 0.0) 
00465  return;
00466       else if (myEle->isSubdomain() == false)          {
00467  theTangent->addMatrix(1.0, *Kc, fact);
00468     }
00469       else {
00470  cerr << "WARNING FE_Element::addKcToTang() - ";
00471  cerr << "- this should not be called on a Subdomain!\n";
00472       }               
00473     }
00474   } 
00475   else {
00476     cerr << "WARNING FE_Element::addKcToTang() - no Element *given ";
00477     cerr << "- subclasses must provide implementation\n";
00478   }             
00479 }    
00480 
00481 
00482 
00483 void  
00484 FE_Element::addKiToTang(double fact)
00485 {
00486   if (myEle != 0) {
00487     // check for a quick return 
00488     if (fact == 0.0) 
00489       return;
00490     else if (myEle->isSubdomain() == false)          
00491       theTangent->addMatrix(1.0, myEle->getKi(), fact);
00492     else {
00493  cerr << "WARNING FE_Element::addKiToTang() - ";
00494  cerr << "- this should not be called on a Subdomain!\n";
00495     }               
00496   } 
00497   else {
00498     cerr << "WARNING FE_Element::addKiToTang() - no Element *given ";
00499     cerr << "- subclasses must provide implementation\n";
00500   }             
00501 }    
00502 
00503 
00504 void  
00505 FE_Element::zeroResidual(void)
00506 {
00507     if (myEle != 0) {
00508  if (myEle->isSubdomain() == false)
00509      theResidual->Zero();
00510  else {
00511      cerr << "WARNING FE_Element::zeroResidual() - ";
00512      cerr << "- this should not be called on a Subdomain!\n";
00513  }              
00514     }
00515     else {
00516  cerr << "WARNING FE_Element::zeroResidual() - no Element *given ";
00517  cerr << "- subclasses must provide implementation\n";
00518     }    
00519 }
00520 
00521 void  
00522 FE_Element::addRtoResidual(double fact)
00523 {
00524     if (myEle != 0) {
00525  // check for a quick return 
00526  if (fact == 0.0) 
00527      return;
00528  else if (myEle->isSubdomain() == false)          
00529   theResidual->addVector(1.0, myEle->getResistingForce(),-fact);
00530  else {
00531      cerr << "WARNING FE_Element::addRtoResidual() - ";
00532      cerr << "- this should not be called on a Subdomain!\n";
00533  }               
00534     }
00535     else {
00536  cerr << "WARNING FE_Element::addRtoResidual() - no Element *given ";
00537  cerr << "- subclasses must provide implementation\n";
00538     }             
00539 }
00540 
00541 
00542 void  
00543 FE_Element::addRIncInertiaToResidual(double fact)
00544 {
00545     if (myEle != 0) {
00546  // check for a quick return 
00547  if (fact == 0.0) 
00548      return;
00549  else if (myEle->isSubdomain() == false)          
00550   theResidual->addVector(1.0, 
00551            myEle->getResistingForceIncInertia(),
00552            -fact);
00553      
00554  else {
00555      cerr << "WARNING FE_Element::addRtoResidual() - ";
00556      cerr << "- this should not be called on a Subdomain!\n";
00557  }               
00558     }
00559     else {
00560  cerr << "WARNING FE_Element::addRtoResidual() - no Element *given ";
00561  cerr << "- subclasses must provide implementation\n";
00562     }             
00563 }
00564 
00565 
00566 void  
00567 FE_Element::addKtForce(const Vector &disp, double fact)
00568 {
00569     if (myEle != 0) {    
00570 
00571  // check for a quick return 
00572  if (fact == 0.0) 
00573      return;
00574  if (myEle->isSubdomain() == false) {
00575      // get the components we need out of the vector
00576      // and place in a temporary vector
00577      Vector tmp(numDOF);
00578      for (int i=0; i<numDOF; i++) {
00579   int loc = myID(i);
00580   if (loc >= 0)
00581       tmp(i) = disp(loc);
00582   else
00583       tmp(i) = 0.0;
00584      }
00585 
00586      if (theResidual->addMatrixVector(1.0, myEle->getTangentStiff(),tmp,fact) < 0) {
00587   cerr << "WARNING FE_Element::addK_Force() - ";
00588   cerr << "- addMatrixVector returned error\n";   
00589      }
00590 
00591  }
00592  else {
00593      cerr << "WARNING FE_Element::addK_Force() - ";
00594      cerr << "- this should not be called on a Subdomain!\n";
00595  }                 
00596     }
00597     else {
00598  cerr << "WARNING FE_Element::addK_Force() - no Element *given ";
00599  cerr << "- subclasses must provide implementation\n";
00600     }                 
00601 }
00602 
00603 
00604 void  
00605 FE_Element::addKsForce(const Vector &disp, double fact)
00606 {
00607     if (myEle != 0) {    
00608 
00609  // check for a quick return 
00610  if (fact == 0.0) 
00611      return;
00612  if (myEle->isSubdomain() == false) {
00613      // get the components we need out of the vector
00614      // and place in a temporary vector
00615      Vector tmp(numDOF);
00616      for (int i=0; i<numDOF; i++) {
00617   int loc = myID(i);
00618   if (loc >= 0)
00619       tmp(i) = disp(loc);
00620   else
00621       tmp(i) = 0.0;  
00622      }
00623  
00624      if (theResidual->addMatrixVector(1.0, myEle->getSecantStiff(),tmp,fact) < 0) {
00625   cerr << "WARNING FE_Element::addK_Force() - ";
00626   cerr << "- addMatrixVector returned error\n";   
00627      }
00628 
00629  }
00630  else {
00631      cerr << "WARNING FE_Element::addK_Force() - ";
00632      cerr << "- this should not be called on a Subdomain!\n";
00633  }                 
00634     }
00635     else {
00636  cerr << "WARNING FE_Element::addK_Force() - no Element *given ";
00637  cerr << "- subclasses must provide implementation\n";
00638     }                 
00639 }
00640 
00641 
00642 void  
00643 FE_Element::addKcForce(const Vector &disp, double fact)
00644 {
00645   // check that a subclass is not being called
00646   if (myEle == 0) {    
00647     cerr << "WARNING FE_Element::addKc_Force() - no Element *given ";
00648     cerr << "- subclasses must provide implementation\n";
00649   }
00650 
00651   // check that the method is not being invoked for a subdomain
00652   if (myEle->isSubdomain() == true) {
00653     cerr << "WARNING FE_Element::addK_Force() - ";
00654     cerr << "- this should not be called on a Subdomain!\n";
00655   }
00656 
00657   // check for some quick returns     
00658   if (Kc == 0) 
00659     return;
00660   if (fact == 0.0) 
00661     return;
00662 
00663 
00664   // get the components we need out of the vector
00665   // and place in a temporary vector
00666   Vector tmp(numDOF);
00667   for (int i=0; i<numDOF; i++) {
00668     int loc = myID(i);
00669     if (loc >= 0)
00670       tmp(i) = disp(loc);
00671     else
00672       tmp(i) = 0.0;  
00673   }
00674 
00675   // now do the matrix vector multiply and addition to the residual
00676   if (theResidual->addMatrixVector(1.0, *Kc, tmp,fact) < 0) {
00677     cerr << "WARNING FE_Element::addK_Force() - ";
00678     cerr << "- addMatrixVector returned error\n";   
00679   }
00680 }
00681 
00682 void  
00683 FE_Element::addKiForce(const Vector &disp, double fact)
00684 {
00685   // check that a subclass is not being called
00686   if (myEle == 0) {    
00687     cerr << "WARNING FE_Element::addKi_Force() - no Element *given ";
00688     cerr << "- subclasses must provide implementation\n";
00689   }
00690 
00691   // check that the method is not being invoked for a subdomain
00692   if (myEle->isSubdomain() == true) {
00693     cerr << "WARNING FE_Element::addK_Force() - ";
00694     cerr << "- this should not be called on a Subdomain!\n";
00695   }
00696 
00697   if (fact == 0.0) 
00698     return;
00699 
00700 
00701   // get the components we need out of the vector
00702   // and place in a temporary vector
00703   Vector tmp(numDOF);
00704   for (int i=0; i<numDOF; i++) {
00705     int loc = myID(i);
00706     if (loc >= 0)
00707       tmp(i) = disp(loc);
00708     else
00709       tmp(i) = 0.0;  
00710   }
00711 
00712   // now do the matrix vector multiply and addition to the residual
00713   if (theResidual->addMatrixVector(1.0, myEle->getKi(), tmp,fact) < 0) {
00714     cerr << "WARNING FE_Element::addK_Force() - ";
00715     cerr << "- addMatrixVector returned error\n";   
00716   }
00717 }
00718 
00719 
00720 
00721 
00722 
00723 
00724 
00725 void  
00726 FE_Element::addD_Force(const Vector &vel, double fact)
00727 {
00728     if (myEle != 0) {    
00729 
00730  // check for a quick return
00731  if (fact == 0.0) 
00732      return;
00733 
00734  if (myEle->isSubdomain() == false) {
00735      // get the components we need out of the vector
00736      // and place in a temporary vector
00737      Vector tmp(numDOF);
00738      for (int i=0; i<numDOF; i++) {
00739   int loc = myID(i);
00740   if (loc >= 0)
00741       tmp(i) = vel(loc);
00742   else
00743       tmp(i) = 0.0;  
00744      }     
00745      
00746      if (theResidual->addMatrixVector(1.0, myEle->getDamp(),tmp,fact) < 0) {
00747   cerr << "WARNING FE_Element::addD_Force() - ";
00748   cerr << "- addMatrixVector returned error\n";   
00749      }     
00750  }
00751  else {
00752      cerr << "WARNING FE_Element::addD_Force() - ";
00753      cerr << "- this should not be called on a Subdomain!\n";
00754  }                  
00755     }
00756     else {
00757  cerr << "WARNING FE_Element::addD_Force() - no Element *given ";
00758  cerr << "- subclasses must provide implementation\n";
00759     }                 
00760 }
00761 
00762 
00763 void  
00764 FE_Element::addM_Force(const Vector &accel, double fact)
00765 {
00766     if (myEle != 0) {    
00767 
00768  // check for a quick return
00769  if (fact == 0.0) 
00770      return;
00771  if (myEle->isSubdomain() == false) {
00772      // get the components we need out of the vector
00773      // and place in a temporary vector
00774      Vector tmp(numDOF);
00775      for (int i=0; i<numDOF; i++) {
00776   int loc = myID(i);
00777   if (loc >= 0)
00778       tmp(i) = accel(loc);
00779   else
00780       tmp(i) = 0.0;  
00781      }     
00782 
00783      if (theResidual->addMatrixVector(1.0, myEle->getMass(),tmp,fact) < 0){
00784   cerr << "WARNING FE_Element::addM_Force() - ";
00785   cerr << "- addMatrixVector returned error\n";   
00786      }  
00787  }
00788  else {
00789      cerr << "WARNING FE_Element::addM_Force() - ";
00790      cerr << "- this should not be called on a Subdomain!\n";
00791  }                  
00792     }
00793     else {
00794  cerr << "WARNING FE_Element::addM_Force() - no Element *given ";
00795  cerr << "- subclasses must provide implementation\n";
00796     }                 
00797 }
00798 
00799 
00800 const Vector &
00801 FE_Element::getTangForce(const Vector &disp, double fact)
00802 {
00803     if (myEle != 0) {    
00804 
00805  // zero out the force vector
00806  theResidual->Zero();
00807 
00808  // check for a quick return
00809  if (fact == 0.0) 
00810      return *theResidual;
00811 
00812  // get the components we need out of the vector
00813  // and place in a temporary vector
00814  Vector tmp(numDOF);
00815  for (int i=0; i<numDOF; i++)
00816      tmp(i) = disp(myID(i));
00817 
00818  if (myEle->isSubdomain() == false) {
00819      // form the tangent again and then add the force
00820      theIntegrator->formEleTangent(this);
00821      if (theResidual->addMatrixVector(1.0, *theTangent,tmp,fact) < 0) {
00822   cerr << "WARNING FE_Element::getTangForce() - ";
00823   cerr << "- addMatrixVector returned error\n";   
00824      }    
00825  }
00826  else {
00827      Subdomain *theSub = (Subdomain *)myEle;
00828      if (theResidual->addMatrixVector(1.0, theSub->getTang(),tmp,fact) < 0) {
00829   cerr << "WARNING FE_Element::getTangForce() - ";
00830   cerr << "- addMatrixVector returned error\n";   
00831      }      
00832  }
00833  return *theResidual;
00834     }
00835     else {
00836  cerr << "WARNING FE_Element::addTangForce() - no Element *given ";
00837  cerr << "- subclasses must provide implementation\n";
00838  return errVector; 
00839     }                 
00840 }
00841 
00842 
00843 
00844 
00845 const Vector &
00846 FE_Element::getKtForce(const Vector &disp, double fact)
00847 {
00848     if (myEle != 0) {    
00849 
00850  // zero out the force vector
00851  theResidual->Zero(); 
00852 
00853  // check for a quick return
00854  if (fact == 0.0) 
00855      return *theResidual;
00856 
00857  // get the components we need out of the vector
00858  // and place in a temporary vector
00859  if (myEle->isSubdomain() == false)  {
00860     Vector tmp(numDOF);
00861     for (int i=0; i<numDOF; i++) {
00862         int loc = myID(i);
00863         if (loc >= 0)
00864      tmp(i) = disp(loc);
00865         else
00866      tmp(i) = 0.0;
00867     }        
00868  
00869     if (theResidual->addMatrixVector(1.0, myEle->getTangentStiff(),
00870          tmp,fact)) {
00871         
00872   cerr << "WARNING FE_Element::getK_Force() - ";
00873   cerr << "- addMatrixVector returned error\n";   
00874      }            
00875         } 
00876  else {
00877      cerr << "WARNING FE_Element::getK_Force() - ";
00878      cerr << "- this should not be called on a Subdomain!\n";
00879  }                   
00880  return *theResidual;    
00881     }
00882     else {
00883  cerr << "WARNING FE_Element::getK_Force() - no Element *given ";
00884  cerr << "- subclasses must provide implementation\n";
00885  return errVector; 
00886     }                 
00887     
00888 
00889 }
00890 
00891 
00892 
00893 const Vector &
00894 FE_Element::getKsForce(const Vector &disp, double fact)
00895 {
00896     if (myEle != 0) {    
00897 
00898  // zero out the force vector
00899  theResidual->Zero(); 
00900 
00901  // check for a quick return
00902  if (fact == 0.0) 
00903      return *theResidual;
00904 
00905  // get the components we need out of the vector
00906  // and place in a temporary vector
00907  if (myEle->isSubdomain() == false)  {
00908     Vector tmp(numDOF);
00909     for (int i=0; i<numDOF; i++) {
00910         int loc = myID(i);
00911         if (loc >= 0)
00912      tmp(i) = disp(loc);
00913         else
00914      tmp(i) = 0.0;
00915     }
00916 
00917  
00918     if (theResidual->addMatrixVector(1.0, myEle->getSecantStiff(),
00919          tmp,fact)) {
00920         
00921   cerr << "WARNING FE_Element::getK_Force() - ";
00922   cerr << "- addMatrixVector returned error\n";   
00923      }            
00924         } 
00925  else {
00926      cerr << "WARNING FE_Element::getK_Force() - ";
00927      cerr << "- this should not be called on a Subdomain!\n";
00928  }                   
00929  return *theResidual;    
00930     }
00931     else {
00932  cerr << "WARNING FE_Element::getK_Force() - no Element *given ";
00933  cerr << "- subclasses must provide implementation\n";
00934  return errVector; 
00935     }                 
00936     
00937 
00938 }
00939 
00940 
00941 
00942 const Vector &
00943 FE_Element::getD_Force(const Vector &vel, double fact)
00944 {
00945 
00946     if (myEle != 0) {
00947 
00948  // zero out the force vector
00949  theResidual->Zero();     
00950 
00951  // check for a quick return
00952  if (fact == 0.0) 
00953      return *theResidual;
00954 
00955  // get the components we need out of the vector
00956  // and place in a temporary vector
00957  if (myEle->isSubdomain() == false)  {
00958       Vector tmp(numDOF);
00959     for (int i=0; i<numDOF; i++) {
00960         int loc = myID(i);
00961         if (loc >= 0)
00962      tmp(i) = vel(loc);
00963         else
00964      tmp(i) = 0.0;
00965     }
00966 
00967     theResidual->addMatrixVector(1.0, myEle->getDamp(),tmp,fact);
00968         }
00969  else {
00970      cerr << "WARNING FE_Element::getD_Force() - ";
00971      cerr << "- this should not be called on a Subdomain!\n";
00972  }                    
00973     
00974  return *theResidual;
00975     }
00976     else {
00977  cerr << "WARNING FE_Element::addPtoResidual() - no Element *given ";
00978  cerr << "- subclasses must provide implementation\n";
00979  return errVector; 
00980     }                 
00981 }
00982 
00983 
00984 
00985 
00986 const Vector &
00987 FE_Element::getM_Force(const Vector &accel, double fact)
00988 {
00989     if (myEle != 0) {
00990  // zero out the force vector
00991  theResidual->Zero(); 
00992 
00993  // check for a quick return
00994  if (fact == 0.0) 
00995      return *theResidual;
00996 
00997  // get the components we need out of the vector
00998  // and place in a temporary vector
00999         if (myEle->isSubdomain() == false)  {
01000     Vector tmp(numDOF);
01001     for (int i=0; i<numDOF; i++) {
01002         int loc = myID(i);
01003         if (loc >= 0)
01004      tmp(i) = accel(loc);
01005         else
01006      tmp(i) = 0.0;
01007     }
01008         
01009     theResidual->addMatrixVector(1.0, myEle->getMass(),tmp,fact);
01010         }
01011  else {
01012      cerr << "WARNING FE_Element::getM_Force() - ";
01013      cerr << "- this should not be called on a Subdomain!\n";
01014  }                   
01015  return *theResidual;
01016     }
01017     else {
01018  cerr << "WARNING FE_Element::getM_Force() - no Element *given ";
01019  cerr << "- subclasses must provide implementation\n";
01020  return errVector;
01021     }                 
01022 }
01023 
01024 
01025 Integrator *
01026 FE_Element::getLastIntegrator(void)
01027 {
01028     return theIntegrator;
01029 }
01030 
01031 const Vector &
01032 FE_Element::getLastResponse(void)
01033 {
01034     if (myEle != 0) {
01035       if (theIntegrator != 0) {
01036  if (theIntegrator->getLastResponse(*theResidual,myID) < 0) {
01037    cerr << "WARNING FE_Element::getLastResponse(void)";
01038    cerr << " - the Integrator had problems with getLastResponse()\n";
01039  }
01040       }
01041       else {
01042  theResidual->Zero();
01043  cerr << "WARNING  FE_Element::getLastResponse()";
01044  cerr << " No Integrator yet passed\n";
01045       }
01046     
01047       Vector &result = *theResidual;
01048       return result;
01049     }
01050     else {
01051  cerr << "WARNING  FE_Element::getLastResponse()";
01052  cerr << " No Element passed in constructor\n";
01053  return errVector;
01054     }
01055 }
01056 
01057 
01058 
01059 
01060 void  
01061 FE_Element::addLocalKtForce(const Vector &disp, double fact)
01062 {
01063     if (myEle != 0) {    
01064  // check for a quick return 
01065  if (fact == 0.0) 
01066      return;
01067  if (myEle->isSubdomain() == false) {
01068      if (theResidual->addMatrixVector(1.0, myEle->getTangentStiff(),
01069         disp, fact) < 0) {
01070 
01071   cerr << "WARNING FE_Element::addLocalK_Force() - ";
01072   cerr << "- addMatrixVector returned error\n";  
01073      }
01074 
01075  }
01076  else {
01077      cerr << "WARNING FE_Element::addLocalK_Force() - ";
01078      cerr << "- this should not be called on a Subdomain!\n";
01079  }                 
01080     }
01081     else {
01082  cerr << "WARNING FE_Element::addLocalK_Force() - no Element *given ";
01083  cerr << "- subclasses must provide implementation\n";
01084     }                 
01085 }
01086 
01087 
01088 void  
01089 FE_Element::addLocalKsForce(const Vector &disp, double fact)
01090 {
01091     if (myEle != 0) {    
01092 
01093  // check for a quick return 
01094  if (fact == 0.0) 
01095      return;
01096  if (myEle->isSubdomain() == false) {
01097  
01098      if (theResidual->addMatrixVector(1.0, myEle->getSecantStiff(),
01099         disp, fact) < 0) {
01100 
01101   cerr << "WARNING FE_Element::addLocalK_Force() - ";
01102   cerr << "- addMatrixVector returned error\n"; 
01103      }
01104  }
01105  else {
01106      cerr << "WARNING FE_Element::addLocalK_Force() - ";
01107      cerr << "- this should not be called on a Subdomain!\n";
01108  }                 
01109     }
01110     else {
01111  cerr << "WARNING FE_Element::addLocalK_Force() - no Element *given ";
01112  cerr << "- subclasses must provide implementation\n";
01113     }                 
01114 }
01115 
01116 
01117 
01118 void  
01119 FE_Element::addLocalKcForce(const Vector &disp, double fact)
01120 {
01121     if (myEle != 0) {    
01122 
01123       // return if Kc has not been initialised
01124       if (Kc == 0) 
01125  return;
01126 
01127       // check for a quick return 
01128       if (fact == 0.0) 
01129  return;
01130 
01131       if (myEle->isSubdomain() == false) {
01132  
01133  if (theResidual->addMatrixVector(1.0, *Kc,
01134       disp, fact) < 0) {
01135 
01136    cerr << "WARNING FE_Element::addLocalK_Force() - ";
01137    cerr << "- addMatrixVector returned error\n"; 
01138  }
01139       }
01140       else {
01141  cerr << "WARNING FE_Element::addLocalK_Force() - ";
01142  cerr << "- this should not be called on a Subdomain!\n";
01143       }                 
01144     }
01145     else {
01146  cerr << "WARNING FE_Element::addLocalK_Force() - no Element *given ";
01147  cerr << "- subclasses must provide implementation\n";
01148     }                 
01149 }
01150 
01151 
01152 void  
01153 FE_Element::addLocalKiForce(const Vector &disp, double fact)
01154 {
01155     if (myEle != 0) {    
01156 
01157       // check for a quick return 
01158       if (fact == 0.0) 
01159  return;
01160 
01161       if (myEle->isSubdomain() == false) {
01162  
01163  if (theResidual->addMatrixVector(1.0, myEle->getKi(),
01164       disp, fact) < 0) {
01165 
01166    cerr << "WARNING FE_Element::addLocalK_Force() - ";
01167    cerr << "- addMatrixVector returned error\n"; 
01168  }
01169       }
01170       else {
01171  cerr << "WARNING FE_Element::addLocalK_Force() - ";
01172  cerr << "- this should not be called on a Subdomain!\n";
01173       }                 
01174     }
01175     else {
01176  cerr << "WARNING FE_Element::addLocalK_Force() - no Element *given ";
01177  cerr << "- subclasses must provide implementation\n";
01178     }                 
01179 }
01180 
01181 
01182 
01183 void  
01184 FE_Element::addLocalD_Force(const Vector &vel, double fact)
01185 {
01186     if (myEle != 0) {    
01187 
01188  // check for a quick return
01189  if (fact == 0.0) 
01190      return;
01191 
01192  if (myEle->isSubdomain() == false) {
01193      
01194      if (theResidual->addMatrixVector(1.0, myEle->getDamp(),
01195         vel, fact) < 0) {
01196 
01197   cerr << "WARNING FE_Element::addLocalD_Force() - ";
01198   cerr << "- addMatrixVector returned error\n"; 
01199      }     
01200  }
01201  else {
01202      cerr << "WARNING FE_Element::addLocalD_Force() - ";
01203      cerr << "- this should not be called on a Subdomain!\n";
01204  }                  
01205     }
01206     else {
01207  cerr << "WARNING FE_Element::addLocalD_Force() - no Element *given ";
01208  cerr << "- subclasses must provide implementation\n";
01209     }                 
01210 }
01211 
01212 
01213 void  
01214 FE_Element::addLocalM_Force(const Vector &accel, double fact)
01215 {
01216     if (myEle != 0) {    
01217 
01218  // check for a quick return
01219  if (fact == 0.0) 
01220      return;
01221  if (myEle->isSubdomain() == false) {
01222      if (theResidual->addMatrixVector(1.0, myEle->getMass(),
01223         accel, fact) < 0){
01224 
01225   cerr << "WARNING FE_Element::addLocalM_Force() - ";
01226   cerr << "- addMatrixVector returned error\n"; 
01227      }  
01228  }
01229  else {
01230      cerr << "WARNING FE_Element::addLocalM_Force() - ";
01231      cerr << "- this should not be called on a Subdomain!\n";
01232  }                  
01233     }
01234     else {
01235  cerr << "WARNING FE_Element::addLocalM_Force() - no Element *given ";
01236  cerr << "- subclasses must provide implementation\n";
01237     }                 
01238 }
01239 
01240 
01241 
Copyright Contact Us