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

DOF_Group.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/05/26 06:20:26 $
00023 // $Source: /usr/local/cvs/OpenSees/SRC/analysis/dof_grp/DOF_Group.cpp,v $
00024                                                                         
00025                                                                         
00026 // File: ~/analysis/dof_grp/DOF_Group.C
00027 //
00028 // Written: fmk 
00029 // Created: 11/96
00030 // Revision: A
00031 //
00032 // Purpose: This file contains the code for implementing the methods
00033 // of the DOF_Group class interface.
00034 //
00035 // What: "@(#) DOF_Group.C, revA"
00036 
00037 
00038 #include <DOF_Group.h>
00039 #include <stdlib.h>
00040 
00041 #include <Node.h>
00042 #include <Vector.h>
00043 #include <Matrix.h>
00044 #include <TransientIntegrator.h>
00045 
00046 #define MAX_NUM_DOF 256
00047 
00048 
00049 // static variables initialisation
00050 Matrix DOF_Group::errMatrix(1,1);
00051 Vector DOF_Group::errVect(1);
00052 Matrix **DOF_Group::theMatrices; // array of pointers to class wide matrices
00053 Vector **DOF_Group::theVectors;  // array of pointers to class widde vectors
00054 int DOF_Group::numDOFs(0);           // number of objects
00055 
00056 
00057 //  DOF_Group(Node *);
00058 // construictor that take the corresponding model node.
00059 
00060 DOF_Group::DOF_Group(int tag, Node *node)
00061 :unbalance(0), tangent(0), myNode(node), 
00062  myTag(tag), myID(node->getNumberDOF()), 
00063  numDOF(node->getNumberDOF())
00064 {
00065     // get number of DOF & verify valid
00066     int numDOF = node->getNumberDOF();
00067     if (numDOF <= 0) {
00068  cerr << "DOF_Group::DOF_Group(Node *) ";
00069  cerr << " node must have at least 1 dof " << *node;
00070  exit(-1);
00071     } 
00072 
00073     // check the ID created is of appropriate size
00074     if (myID.Size() != numDOF) {
00075  cerr << "DOF_Group::DOF_Group(Node *) ";
00076  cerr << " ran out of memory creating ID for node " << *node;
00077  exit(-1);
00078     }
00079 
00080     // initially set all the IDs to be -2
00081     for (int i=0; i<numDOF; i++)
00082  myID(i) = -2;
00083     
00084     // if this is the first DOF_Group we now
00085     // create the arrays used to store pointers to class wide
00086     // matrix and vector objects used to return tangent and residual
00087     if (numDOFs == 0) {
00088  theMatrices = new Matrix *[MAX_NUM_DOF+1];
00089  theVectors  = new Vector *[MAX_NUM_DOF+1];
00090  
00091  if (theMatrices == 0 || theVectors == 0) {
00092      cerr << "DOF_Group::DOF_Group(Node *) ";
00093      cerr << " ran out of memory";     
00094  }
00095  for (int i=0; i<MAX_NUM_DOF; i++) {
00096      theMatrices[i] = 0;
00097      theVectors[i] = 0;
00098  }
00099     }    
00100     
00101     // set the pointers for the tangent and residual
00102     if (numDOF <= MAX_NUM_DOF) {
00103  // use class wide objects
00104  if (theVectors[numDOF] == 0) {
00105      // have to create matrix and vector of size as none yet created
00106      theVectors[numDOF] = new Vector(numDOF);
00107      theMatrices[numDOF] = new Matrix(numDOF,numDOF);
00108      unbalance = theVectors[numDOF];
00109      tangent = theMatrices[numDOF];
00110      if (unbalance == 0 || unbalance->Size() != numDOF || 
00111   tangent == 0 || tangent->noCols() != numDOF) {  
00112   cerr << "DOF_Group::DOF_Group(Node *) ";
00113   cerr << " ran out of memory for vector/Matrix of size :";
00114   cerr << numDOF << endl;
00115   exit(-1);
00116      }
00117  } else {
00118      unbalance = theVectors[numDOF];
00119      tangent = theMatrices[numDOF];
00120  }
00121     } else {
00122  // create matrices and vectors for each object instance
00123  unbalance = new Vector(numDOF);
00124  tangent = new Matrix(numDOF, numDOF);
00125  if (unbalance == 0 || unbalance->Size() ==0 ||
00126      tangent ==0 || tangent->noRows() ==0) {
00127      
00128      cerr << "DOF_Group::DOF_Group(Node *) ";
00129      cerr << " ran out of memory for vector/Matrix of size :";
00130      cerr << numDOF << endl;
00131      exit(-1);
00132  }
00133     }
00134     
00135     numDOFs++;
00136 }
00137 
00138 
00139 DOF_Group::DOF_Group(int tag, int ndof)
00140 :unbalance(0), tangent(0), myNode(0), 
00141  myTag(tag), myID(ndof), 
00142  numDOF(ndof)
00143 {
00144     // get number of DOF & verify valid
00145     int numDOF = ndof;
00146     if (numDOF <= 0) {
00147  cerr << "DOF_Group::DOF_Group(int, int ndof) ";
00148  cerr << ndof << " ndof specified, there must be at least 1\n";
00149  exit(-1);
00150     } 
00151 
00152     // check the ID created is of appropriate size
00153     if (myID.Size() != numDOF) {
00154  cerr << "DOF_Group::DOF_Group(int, int ndof) ";
00155  cerr << " ran out of memory creating ID of size " << ndof << endl;
00156  exit(-1);
00157     }
00158 
00159     // initially set all the IDs to be -2
00160     for (int i=0; i<numDOF; i++)
00161  myID(i) = -2;
00162     
00163     // if this is the first DOF_Group we now
00164     // create the arrays used to store pointers to class wide
00165     // matrix and vector objects used to return tangent and residual
00166     if (numDOFs == 0) {
00167  theMatrices = new Matrix *[MAX_NUM_DOF+1];
00168  theVectors  = new Vector *[MAX_NUM_DOF+1];
00169  
00170  if (theMatrices == 0 || theVectors == 0) {
00171      cerr << "DOF_Group::DOF_Group(int, int ndof) ";
00172      cerr << " ran out of memory";     
00173  }
00174  for (int i=0; i<MAX_NUM_DOF; i++) {
00175      theMatrices[i] = 0;
00176      theVectors[i] = 0;
00177  }
00178     }    
00179 
00180     // set the pointers for the tangent and residual
00181     if (numDOF <= MAX_NUM_DOF) {
00182  // use class wide objects
00183  if (theVectors[numDOF] == 0) {
00184      // have to create matrix and vector of size as none yet created
00185      theVectors[numDOF] = new Vector(numDOF);
00186      theMatrices[numDOF] = new Matrix(numDOF,numDOF);
00187      unbalance = theVectors[numDOF];
00188      tangent = theMatrices[numDOF];
00189      if (unbalance == 0 || unbalance->Size() != numDOF || 
00190   tangent == 0 || tangent->noCols() != numDOF) {  
00191   cerr << "DOF_Group::DOF_Group(int, int ndof) ";
00192   cerr << " ran out of memory for vector/Matrix of size :";
00193   cerr << numDOF << endl;
00194   exit(-1);
00195      }
00196  } else {
00197      unbalance = theVectors[numDOF];
00198      tangent = theMatrices[numDOF];
00199  }
00200     } else {
00201  // create matrices and vectors for each object instance
00202  unbalance = new Vector(numDOF);
00203  tangent = new Matrix(numDOF, numDOF);
00204  if (unbalance == 0 || tangent ==0 ||
00205      tangent ==0 || tangent->noRows() ==0) {
00206      
00207      cerr << "DOF_Group::DOF_Group(int, int ndof) ";
00208      cerr << " ran out of memory for vector/Matrix of size :";
00209      cerr << numDOF << endl;
00210      exit(-1);
00211  }
00212     }
00213     
00214     numDOFs++;
00215 }
00216 
00217 // ~DOF_Group();    
00218 // destructor.
00219 
00220 DOF_Group::~DOF_Group()
00221 {
00222     numDOFs--;
00223 
00224     // set the pointer in the associated Node to 0, to stop
00225     // segmentation fault if node tries to use this object after destroyed
00226     if (myNode != 0) {
00227  myNode->setDOF_GroupPtr(0);
00228     }
00229     
00230     int numDOF = unbalance->Size();
00231     
00232     // delete tangent and residual if created specially
00233     if (numDOF > MAX_NUM_DOF) {
00234  if (tangent != 0) delete tangent;
00235  if (unbalance != 0) delete unbalance;
00236     }
00237 
00238     // if this is the last FE_Element, clean up the
00239     // storage for the matrix and vector objects
00240     if (numDOFs == 0) {
00241  for (int i=0; i<MAX_NUM_DOF; i++) {
00242      if (theVectors[i] != 0)
00243   delete theVectors[i];
00244      if (theMatrices[i] != 0)
00245   delete theMatrices[i];
00246  } 
00247  delete [] theMatrices;
00248  delete [] theVectors;
00249     }    
00250 }    
00251 
00252 // void setID(int index, int value);
00253 // Method to set the corresponding index of the ID to value.
00254 
00255 void
00256 DOF_Group::setID(int index, int value)
00257 {
00258     if ((index >= 0) && (index < numDOF))
00259  myID(index) = value;
00260     else {
00261  cerr << "WARNING DOF_Group::setID - invalid location ";
00262  cerr << index << " in ID of size " << numDOF << endl;
00263     } 
00264 }
00265 
00266 // void setID(const ID &);
00267 // Method to set the ID to be same as that given.
00268 
00269 void
00270 DOF_Group::setID(const ID &copy)
00271 {
00272     myID = copy;
00273 }
00274  
00275 
00276 // const ID &getID(void) const;
00277 // Method to return the current ID.
00278 
00279 const ID &
00280 DOF_Group::getID(void) const
00281 {
00282     return myID;
00283 }
00284 
00285 
00286 
00287 int
00288 DOF_Group::getNumDOF(void) const
00289 {
00290     return numDOF;
00291 }
00292 
00293 int
00294 DOF_Group::getNodeTag(void) const
00295 {
00296     if (myNode != 0)
00297      return myNode->getTag();
00298     else
00299      return -1;
00300 }
00301 
00302 int
00303 DOF_Group::getNumFreeDOF(void) const
00304 {
00305     int numFreeDOF = numDOF;
00306     for (int i=0; i<numDOF; i++)
00307  if (myID(i) < 0)
00308      numFreeDOF--;
00309     
00310     return numFreeDOF;
00311 }
00312 
00313 int
00314 DOF_Group::getNumConstrainedDOF(void) const
00315 {   
00316     int numConstr = 0;
00317     for (int i=0; i<numDOF; i++)
00318  if (myID(i) < 0)
00319      numConstr++;    
00320 
00321     return numConstr;
00322 }    
00323 
00324 
00325 
00326 const Matrix &
00327 DOF_Group::getTangent(Integrator *theIntegrator) 
00328 { 
00329     if (theIntegrator != 0)
00330  theIntegrator->formNodTangent(this);    
00331     return *tangent;
00332 }
00333 
00334 void  
00335 DOF_Group::zeroTangent(void)
00336 {
00337     tangent->Zero();
00338 }
00339 
00340 
00341 void  
00342 DOF_Group::addMtoTang(double fact)
00343 {
00344     if (myNode != 0) {
00345  if (tangent->addMatrix(1.0, myNode->getMass(), fact) < 0) {
00346      cerr << "DOF_Group::addMtoTang(void) ";
00347      cerr << " invoking addMatrix() on the tangent failed\n";     
00348  }
00349     }
00350     else {
00351  cerr << "DOF_Group::addMtoTang(void) - no Node associated";
00352  cerr << " subclass should provide the method \n";     
00353     } 
00354 }
00355 
00356 
00357 
00358 void
00359 DOF_Group::zeroUnbalance(void) 
00360 {
00361     unbalance->Zero();
00362 }
00363 
00364 
00365 const Vector &
00366 DOF_Group::getUnbalance(Integrator *theIntegrator)
00367 {
00368     if (theIntegrator != 0)
00369  theIntegrator->formNodUnbalance(this);
00370 
00371     return *unbalance;
00372 }
00373 
00374 
00375 void
00376 DOF_Group::addPtoUnbalance(double fact)
00377 {
00378     if (myNode != 0) {
00379  if (unbalance->addVector(1.0, myNode->getUnbalancedLoad(), fact) < 0) {
00380      cerr << "DOF_Group::addPIncInertiaToUnbalance() -";
00381      cerr << " invoking addVector() on the unbalance failed\n";     
00382  }
00383     }
00384     else {
00385  cerr << "DOF_Group::addPtoUnbalance() - no Node associated";
00386  cerr << " subclass should provide the method \n";     
00387     }  
00388 }
00389 
00390 
00391 void
00392 DOF_Group::addPIncInertiaToUnbalance(double fact)
00393 {
00394     if (myNode != 0) {
00395  if (unbalance->addVector(1.0, myNode->getUnbalancedLoadIncInertia(), 
00396      fact) < 0) {
00397 
00398      cerr << "DOF_Group::addPIncInertiaToUnbalance() - ";
00399      cerr << " invoking addVector() on the unbalance failed\n";     
00400  }
00401     }
00402      else {
00403  cerr << "DOF_Group::addPIncInertiaToUnbalance() - no Node associated";
00404  cerr << " subclass should provide the method \n";     
00405     }  
00406 }
00407 
00408 
00409 void  
00410 DOF_Group::addM_Force(const Vector &Udotdot, double fact)
00411 {
00412     if (myNode == 0) {
00413  cerr << "DOF_Group::addM_Force() - no Node associated"; 
00414  cerr << " subclass should not call this method \n";     
00415  return;
00416     }
00417 
00418     Vector accel(numDOF);
00419     // get accel for the unconstrained dof
00420     for (int i=0; i<numDOF; i++) {
00421  int loc = myID(i);
00422  if (loc >= 0)
00423      accel(i) = Udotdot(loc); 
00424  else accel(i) = 0.0;
00425     }
00426  
00427     if (unbalance->addMatrixVector(1.0, myNode->getMass(), accel, fact) < 0) {  
00428  cerr << "DOF_Group::addM_Force() ";
00429  cerr << " invoking addMatrixVector() on the unbalance failed\n";
00430     }
00431     else {
00432 
00433     }  
00434 }
00435 
00436 
00437 const Vector & 
00438 DOF_Group::getCommittedDisp(void)
00439 {
00440     if (myNode == 0) {
00441  cerr << "DOF_Group::getCommittedDisp: no associated Node ";
00442  cerr << " returning the error Vector\n";
00443  return errVect;
00444     }
00445     return myNode->getDisp();
00446 }
00447 
00448 
00449 const Vector & 
00450 DOF_Group::getCommittedVel(void)
00451 {
00452     if (myNode == 0) {
00453  cerr << "DOF_Group::getCommittedVel: no associated Node ";
00454  cerr << " returning the error Vector\n";
00455  return errVect; 
00456     }
00457     return myNode->getVel();
00458 }
00459 
00460 
00461 const Vector & 
00462 DOF_Group::getCommittedAccel(void)
00463 {
00464     if (myNode == 0) {
00465  cerr << "DOF_Group::getCommittedAccel: no associated Node ";
00466  cerr << " returning the error Vector\n";
00467  return errVect; 
00468     }
00469     return myNode->getAccel();
00470 }
00471 
00472 // void setNodeDisp(const Vector &u);
00473 // Method to set the corresponding nodes displacements to the
00474 // values in u, components identified by myID;
00475 
00476 void
00477 DOF_Group::setNodeDisp(const Vector &u)
00478 {
00479     if (myNode == 0) {
00480  cerr << "DOF_Group::setNodeDisp: no associated Node\n";
00481  return;
00482     }
00483     
00484     Vector &disp = *unbalance;
00485     disp = myNode->getTrialDisp();
00486     int i;
00487     
00488     // get disp for my dof out of vector u
00489     for (i=0; i<numDOF; i++) {
00490  int loc = myID(i);
00491  if (loc >= 0)
00492      disp(i) = u(loc);  
00493     }
00494 
00495     myNode->setTrialDisp(disp);
00496 }
00497  
00498  
00499 // void setNodeVel(const Vector &udot);
00500 // Method to set the corresponding nodes velocities to the
00501 // values in udot, components identified by myID;
00502 
00503 void
00504 DOF_Group::setNodeVel(const Vector &udot)
00505 {
00506 
00507     if (myNode == 0) {
00508  cerr << "DOF_Group::setNodeVel: 0 Node Pointer\n";
00509  return;
00510     }
00511     
00512     Vector &vel = *unbalance;
00513     vel = myNode->getTrialVel();
00514     int i;
00515     
00516     // get vel for my dof out of vector udot
00517     for (i=0; i<numDOF; i++) {
00518  int loc = myID(i);      
00519  if (loc >= 0) 
00520      vel(i) = udot(loc);  
00521     }
00522 
00523     myNode->setTrialVel(vel);
00524 
00525 }
00526 
00527 
00528 
00529 // void setNodeAccel(const Vector &udotdot);
00530 // Method to set the corresponding nodes accelerations to the
00531 // values in udotdot, components identified by myID;
00532 
00533 void
00534 DOF_Group::setNodeAccel(const Vector &udotdot)
00535 {
00536 
00537     if (myNode == 0) {
00538  cerr << "DOF_Group::setNodeAccel: 0 Node Pointer\n";
00539  return;
00540     }
00541 
00542     Vector &accel = *unbalance;;
00543     accel = myNode->getTrialAccel();
00544     int i;
00545     
00546     // get disp for the unconstrained dof
00547     for (i=0; i<numDOF; i++) {
00548  int loc = myID(i);       
00549  if (loc >= 0)
00550      accel(i) = udotdot(loc); 
00551     }
00552 
00553     myNode->setTrialAccel(accel);
00554 }
00555 
00556 
00557 // void setNodeIncrDisp(const Vector &u);
00558 // Method to set the corresponding nodes displacements to the
00559 // values in u, components identified by myID;
00560 
00561 void
00562 DOF_Group::incrNodeDisp(const Vector &u)
00563 {
00564     if (myNode == 0) {
00565  cerr << "DOF_Group::setNodeDisp: 0 Node Pointer\n";
00566  exit(-1);
00567     }
00568 
00569     Vector &disp = *unbalance;;
00570 
00571     if (disp.Size() == 0) {
00572       cerr << "DOF_Group::setNodeIncrDisp - out of space\n";
00573       return;
00574     }
00575     int i;
00576 
00577     // get disp for my dof out of vector u
00578     for (i=0; i<numDOF; i++) {
00579  int loc = myID(i);        
00580  if (loc >= 0)
00581      disp(i) = u(loc);  
00582  else disp(i) = 0.0;  
00583     }
00584 
00585     myNode->incrTrialDisp(disp);
00586 
00587 }
00588  
00589  
00590 // void setNodeincrVel(const Vector &udot);
00591 // Method to set the corresponding nodes velocities to the
00592 // values in udot, components identified by myID;
00593 
00594 void
00595 DOF_Group::incrNodeVel(const Vector &udot)
00596 {
00597 
00598     if (myNode == 0) {
00599  cerr << "DOF_Group::setNodeVel: 0 Node Pointer\n";
00600  exit(-1);
00601     }
00602     
00603     Vector &vel = *unbalance;
00604     int i;
00605     
00606     // get vel for my dof out of vector udot
00607     for (i=0; i<numDOF; i++) {
00608  int loc = myID(i);
00609  if (loc >= 0)
00610      vel(i) = udot(loc);  // -1 for dof labelled 1 through ndof
00611  else  vel(i) = 0.0;
00612     }
00613     myNode->incrTrialVel(vel);
00614 }
00615 
00616 
00617 
00618 // void setNodeIncrAccel(const Vector &udotdot);
00619 // Method to set the corresponding nodes accelerations to the
00620 // values in udotdot, components identified by myID;
00621 
00622 void
00623 DOF_Group::incrNodeAccel(const Vector &udotdot)
00624 {
00625 
00626     if (myNode == 0) {
00627  cerr << "DOF_Group::setNodeAccel: 0 Node Pointer\n";
00628  exit(-1);
00629     }
00630 
00631     Vector &accel = *unbalance;
00632     int i;
00633     
00634     // get disp for the unconstrained dof
00635     for (i=0; i<numDOF; i++) {
00636  int loc = myID(i);
00637  if (loc >= 0)
00638      accel(i) = udotdot(loc); 
00639  else accel(i) = 0.0;
00640     }    
00641     myNode->incrTrialAccel(accel);
00642 }
00643 
00644 
00645 
00646 void
00647 DOF_Group::setEigenvector(int mode, const Vector &theVector)
00648 {
00649 
00650     if (myNode == 0) {
00651  cerr << "DOF_Group::setNodeAccel: 0 Node Pointer\n";
00652  exit(-1);
00653     }
00654 
00655     Vector &eigenvector = *unbalance;
00656     int i;
00657     
00658     // get disp for the unconstrained dof
00659     for (i=0; i<numDOF; i++) {
00660  int loc = myID(i);
00661  if (loc >= 0)
00662      eigenvector(i) = theVector(loc); 
00663  else eigenvector(i) = 0.0;
00664     }    
00665     myNode->setEigenvector(mode, eigenvector);
00666 }
00667 
00668 
00669 
00670 int
00671 DOF_Group::getTag(void) const
00672 {
00673     return myTag;
00674 }
00675 
00676 Matrix *
00677 DOF_Group::getT(void)
00678 {
00679     return 0;
00680 }
00681 
00682 
00683 
00684 void  
00685 DOF_Group::addLocalM_Force(const Vector &accel, double fact)
00686 {
00687     if (myNode != 0) {
00688  if (unbalance->addMatrixVector(1.0, myNode->getMass(), accel, fact) < 0) {  
00689            
00690      cerr << "DOF_Group::addM_Force() ";
00691      cerr << " invoking addMatrixVector() on the unbalance failed\n"; 
00692  }
00693     }
00694     else {
00695  cerr << "DOF_Group::addM_Force() - no Node associated";
00696  cerr << " subclass should not call this method \n";     
00697     }  
00698 }
00699 
00700 
00701 
00702 
00703 
Copyright Contact Us