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

TransformationDOF_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/03 06:14:16 $
00023 // $Source: /usr/local/cvs/OpenSees/SRC/analysis/dof_grp/TransformationDOF_Group.cpp,v $
00024                                                                         
00025                                                                         
00026 // File: ~/analysis/dof_grp/TransformationDOF_Group.C
00027 //
00028 // Written: fmk 
00029 // Created: 05/99
00030 // Revision: A
00031 //
00032 // Purpose: This file contains the code for implementing the methods
00033 // of the TransformationDOF_Group class interface.
00034 //
00035 // What: "@(#) TransformationDOF_Group.C, revA"
00036 
00037 
00038 #include <TransformationDOF_Group.h>
00039 #include <stdlib.h>
00040 
00041 #include <Domain.h>
00042 #include <Node.h>
00043 #include <Vector.h>
00044 #include <Matrix.h>
00045 #include <TransientIntegrator.h>
00046 #include <MP_Constraint.h>
00047 #include <SP_Constraint.h>
00048 #include <SP_ConstraintIter.h>
00049 
00050 #define MAX_NUM_DOF 16
00051 
00052 
00053 // static variables initialisation
00054 Matrix **TransformationDOF_Group::modMatrices; 
00055 Vector **TransformationDOF_Group::modVectors;  
00056 int TransformationDOF_Group::numTransDOFs(0);     // number of objects
00057 
00058 TransformationDOF_Group::TransformationDOF_Group(int tag, Node *node, 
00059        MP_Constraint *mp)  
00060 :DOF_Group(tag,node),
00061  theMP(mp),Trans(0),modTangent(0),modUnbalance(0),modID(0),theSPs(0)
00062 {
00063     // determine the number of DOF 
00064     int numNodalDOF = node->getNumberDOF();
00065     const ID &retainedDOF = mp->getRetainedDOFs();
00066     const ID &constrainedDOF = mp->getConstrainedDOFs();    
00067     int numNodalDOFConstrained = constrainedDOF.Size();
00068     int numConstrainedNodeRetainedDOF = numNodalDOF - numNodalDOFConstrained;
00069     int numRetainedNodeDOF = retainedDOF.Size();
00070 
00071     modNumDOF = numConstrainedNodeRetainedDOF + numRetainedNodeDOF;
00072 
00073     // create space for the SP_Constraint array
00074     theSPs = new SP_Constraint *[numNodalDOF];
00075     for (int ii=0; ii<numNodalDOF; ii++) 
00076  theSPs[ii] = 0;
00077 
00078     /***********************
00079     // set the SP_Constraint corresponding to the dof in modID
00080     Domain *theDomain=node->getDomain();
00081     int nodeTag = node->getTag();    
00082     SP_ConstraintIter &theSPIter = theDomain->getSPs();
00083     SP_Constraint *sp;
00084     while ((sp = theSPIter()) != 0) {
00085  if (sp->getNodeTag() == nodeTag) {
00086      int dof = sp->getDOF_Number();
00087      int loc = 0;
00088      for (int i=0; i<dof; i++) 
00089   if (constrainedDOF.getLocation(i) < 0)
00090       loc++;
00091      theSPs[loc] = sp;
00092  }
00093     }
00094     *******************/
00095      
00096     // create ID and transformation matrix
00097     modID = new ID(modNumDOF);
00098     Trans = new Matrix(numNodalDOF, modNumDOF);
00099 
00100     if (modID == 0 || modID->Size() == 0 ||
00101  Trans == 0 || Trans->noRows() == 0) {
00102  
00103  cerr << "FATAL TransformationDOF_Group::TransformationDOF_Group() -";
00104  cerr << " ran out of memory for size: " << modNumDOF << endl;
00105  exit(-1);
00106     }
00107 
00108     // initially set the id values to -2 for any dof still due to constrained node
00109     for (int i=0; i<numConstrainedNodeRetainedDOF; i++)
00110  (*modID)(i) = -2;
00111     
00112     // for all the constrained dof values set to -1
00113     for (int j=numConstrainedNodeRetainedDOF; j<modNumDOF; j++)
00114  (*modID)(j) = -1;
00115 
00116     // for all the dof corresponding to the retained node set initially to -1
00117     // we don't initially assign these equation nos. - this is done in doneID()
00118     for (int k=numConstrainedNodeRetainedDOF; k<modNumDOF; k++)
00119  (*modID)(k) = -1;
00120     
00121     // if this is the first TransformationDOF_Group we now
00122     // create the arrays used to store pointers to class wide
00123     // matrix and vector objects used to return modTangent and residual
00124     if (numTransDOFs == 0) {
00125  modMatrices = new Matrix *[MAX_NUM_DOF+1];
00126  modVectors  = new Vector *[MAX_NUM_DOF+1];
00127  
00128  if (modMatrices == 0 || modVectors == 0) {
00129      cerr << "TransformationDOF_Group::TransformationDOF_Group(Node *) ";
00130      cerr << " ran out of memory";     
00131  }
00132  for (int i=0; i<MAX_NUM_DOF; i++) {
00133      modMatrices[i] = 0;
00134      modVectors[i] = 0;
00135  }
00136     }    
00137 
00138     // set the pointers for the modTangent and residual
00139     if (modNumDOF <= MAX_NUM_DOF) {
00140  // use class wide objects
00141  if (modVectors[modNumDOF] == 0) {
00142      // have to create matrix and vector of size as none yet created
00143      modVectors[modNumDOF] = new Vector(modNumDOF);
00144      modMatrices[modNumDOF] = new Matrix(modNumDOF,modNumDOF);
00145      modUnbalance = modVectors[modNumDOF];
00146      modTangent = modMatrices[modNumDOF];
00147      if (modUnbalance == 0 || modUnbalance->Size() != modNumDOF || 
00148   modTangent == 0 || modTangent->noCols() != modNumDOF) {  
00149   cerr << "TransformationDOF_Group::TransformationDOF_Group(Node *) ";
00150   cerr << " ran out of memory for vector/Matrix of size :";
00151   cerr << modNumDOF << endl;
00152   exit(-1);
00153      }
00154  } else {
00155      modUnbalance = modVectors[modNumDOF];
00156      modTangent = modMatrices[modNumDOF];
00157  }
00158     } else {
00159  // create matrices and vectors for each object instance
00160  modUnbalance = new Vector(modNumDOF);
00161  modTangent = new Matrix(modNumDOF, modNumDOF);
00162  if (modUnbalance == 0 || modTangent ==0 ||
00163      modTangent ==0 || modTangent->noRows() ==0) {
00164      
00165      cerr << "TransformationDOF_Group::TransformationDOF_Group(Node *) ";
00166      cerr << " ran out of memory for vector/Matrix of size :";
00167      cerr << modNumDOF << endl;
00168      exit(-1);
00169  }
00170     }
00171     
00172     numTransDOFs++;
00173 }
00174 
00175 void 
00176 TransformationDOF_Group::setID(int dof, int value)
00177 {
00178     if (theMP == 0)
00179  this->DOF_Group::setID(dof,value);
00180     else
00181  (*modID)(dof) = value;
00182 }
00183  
00184 
00185 TransformationDOF_Group::TransformationDOF_Group(int tag, Node *node)
00186 :DOF_Group(tag,node),
00187  theMP(0),Trans(0),modTangent(0),modUnbalance(0),modID(0),theSPs(0) 
00188 {
00189     modNumDOF = node->getNumberDOF();
00190 
00191     // create space for the SP_Constraint array
00192     theSPs = new SP_Constraint *[modNumDOF];
00193     for (int i=0; i<modNumDOF; i++) 
00194  theSPs[i] = 0;
00195 
00196     // set the SP_Constraint corresponding to the dof in myID
00197     Domain *theDomain=node->getDomain();
00198     int nodeTag = node->getTag();
00199     SP_ConstraintIter &theSPIter = theDomain->getSPs();
00200     SP_Constraint *sp;
00201     while ((sp = theSPIter()) != 0) {
00202  if (sp->getNodeTag() == nodeTag) {
00203      int dof = sp->getDOF_Number();
00204      theSPs[dof] = sp;
00205  }
00206     }    
00207     
00208     // if this is the first TransformationDOF_Group we now
00209     // create the arrays used to store pointers to class wide
00210     // matrix and vector objects used to return modTangent and residual
00211     if (numTransDOFs == 0) {
00212  modMatrices = new Matrix *[MAX_NUM_DOF+1];
00213  modVectors  = new Vector *[MAX_NUM_DOF+1];
00214  
00215  if (modMatrices == 0 || modVectors == 0) {
00216      cerr << "TransformationDOF_Group::TransformationDOF_Group(Node *) ";
00217      cerr << " ran out of memory";     
00218  }
00219  for (int i=0; i<MAX_NUM_DOF; i++) {
00220      modMatrices[i] = 0;
00221      modVectors[i] = 0;
00222  }
00223     }    
00224 
00225     numTransDOFs++;
00226 }
00227 
00228 
00229 // ~TransformationDOF_Group();    
00230 // destructor.
00231 
00232 TransformationDOF_Group::~TransformationDOF_Group()
00233 {
00234     numTransDOFs--;
00235 
00236     // delete modTangent and residual if created specially
00237     if (modNumDOF > MAX_NUM_DOF) {
00238  if (modTangent != 0) delete modTangent;
00239  if (modUnbalance != 0) delete modUnbalance;
00240     }
00241     
00242     if (modID != 0) delete modID;
00243     if (Trans != 0) delete Trans;
00244     if (theSPs != 0) delete [] theSPs;
00245 
00246     // if this is the last FE_Element, clean up the
00247     // storage for the matrix and vector objects
00248     if (numTransDOFs == 0) {
00249  for (int i=0; i<MAX_NUM_DOF; i++) {
00250      if (modVectors[i] != 0)
00251   delete modVectors[i];
00252      if (modMatrices[i] != 0)
00253   delete modMatrices[i];
00254  } 
00255  delete [] modMatrices;
00256  delete [] modVectors;
00257     }    
00258 }    
00259 
00260 
00261 const ID &
00262 TransformationDOF_Group::getID(void) const
00263 {
00264     if (modID != 0)
00265  return *modID;
00266     else
00267  return this->DOF_Group::getID();
00268 }
00269 
00270 int
00271 TransformationDOF_Group::getNumDOF(void) const
00272 {
00273     return modNumDOF;
00274 }
00275 
00276 
00277 int
00278 TransformationDOF_Group::getNumFreeDOF(void) const
00279 {
00280     if (modID != 0) {
00281  int numFreeDOF = modNumDOF;
00282  for (int i=0; i<modNumDOF; i++)
00283      if ((*modID)(i) < 0)
00284   numFreeDOF--;
00285  return numFreeDOF; 
00286     } else
00287  return this->DOF_Group::getNumFreeDOF();
00288 }
00289 
00290 int
00291 TransformationDOF_Group::getNumConstrainedDOF(void) const
00292 {   
00293     if (modID != 0) {    
00294  int numConstr = 0;
00295  for (int i=0; i<modNumDOF; i++)
00296      if ((*modID)(i) < 0)
00297   numConstr++;    
00298  
00299  return numConstr;
00300     } else
00301  return this->DOF_Group::getNumConstrainedDOF(); 
00302 }    
00303 
00304 
00305 
00306 const Matrix &
00307 TransformationDOF_Group::getTangent(Integrator *theIntegrator) 
00308 {
00309     const Matrix &unmodTangent = this->DOF_Group::getTangent(theIntegrator);
00310     Matrix *T = this->getT();
00311     if (T != 0) {
00312  *modTangent = (*T) ^ unmodTangent * (*T);
00313  return *modTangent;
00314  
00315     } else
00316  return unmodTangent;
00317 }
00318 
00319 const Vector &
00320 TransformationDOF_Group::getUnbalance(Integrator *theIntegrator)
00321 {
00322     const Vector &unmodUnbalance = 
00323  this->DOF_Group::getUnbalance(theIntegrator);
00324 
00325     Matrix *T = this->getT();
00326     if (T != 0) {
00327  *modUnbalance = (*T) ^ unmodUnbalance;
00328  return *modUnbalance;    
00329     } else
00330  return unmodUnbalance;
00331 }
00332 
00333 
00334 const Vector & 
00335 TransformationDOF_Group::getCommittedDisp(void)
00336 {
00337     const Vector &responseC = myNode->getDisp();
00338     
00339     if (theMP == 0)
00340  return responseC;
00341     else {
00342  int retainedNode = theMP->getNodeRetained();
00343  Domain *theDomain = myNode->getDomain();
00344  Node *retainedNodePtr = theDomain->getNode(retainedNode);
00345  const Vector &responseR = retainedNodePtr->getDisp();
00346  const ID &retainedDOF = theMP->getRetainedDOFs();
00347  const ID &constrainedDOF = theMP->getConstrainedDOFs();     
00348  int numCNodeDOF = myNode->getNumberDOF();
00349  int numRetainedNodeDOF = retainedDOF.Size();
00350 
00351  int loc = 0;
00352  for (int i=0; i<numCNodeDOF; i++) {
00353      if (constrainedDOF.getLocation(i) < 0) {
00354   (*modUnbalance)(loc) = responseC(i);
00355   loc++;
00356      } 
00357  }
00358  for (int j=0; j<numRetainedNodeDOF; j++) {
00359      int dof = retainedDOF(j);
00360      (*modUnbalance)(loc) = responseR(dof);
00361      loc++;
00362  }
00363 
00364  return *modUnbalance;
00365     }
00366 }
00367 
00368 const Vector & 
00369 TransformationDOF_Group::getCommittedVel(void)
00370 {
00371     const Vector &responseC = myNode->getVel();
00372     
00373     if (theMP == 0)
00374  return responseC;
00375     else {
00376  int retainedNode = theMP->getNodeRetained();
00377  Domain *theDomain = myNode->getDomain();
00378  Node *retainedNodePtr = theDomain->getNode(retainedNode);
00379  const Vector &responseR = retainedNodePtr->getVel();
00380  const ID &retainedDOF = theMP->getRetainedDOFs();
00381  const ID &constrainedDOF = theMP->getConstrainedDOFs();     
00382  int numCNodeDOF = myNode->getNumberDOF();
00383  int numRetainedNodeDOF = retainedDOF.Size();
00384 
00385  int loc = 0;
00386  for (int i=0; i<numCNodeDOF; i++) {
00387      if (constrainedDOF.getLocation(i) < 0) {
00388   (*modUnbalance)(loc) = responseC(i);
00389   loc++;
00390      } 
00391  }
00392  for (int j=0; j<numRetainedNodeDOF; j++) {
00393      int dof = retainedDOF(j);
00394      (*modUnbalance)(loc) = responseR(dof);
00395      loc++;
00396  }
00397  
00398  return *modUnbalance;
00399     }
00400 }
00401 
00402 
00403 const Vector & 
00404 TransformationDOF_Group::getCommittedAccel(void)
00405 {
00406     const Vector &responseC = myNode->getAccel();
00407     
00408     if (theMP == 0)
00409  return responseC;
00410     else {
00411  int retainedNode = theMP->getNodeRetained();
00412  Domain *theDomain = myNode->getDomain();
00413  Node *retainedNodePtr = theDomain->getNode(retainedNode);
00414  const Vector &responseR = retainedNodePtr->getAccel();
00415  const ID &retainedDOF = theMP->getRetainedDOFs();
00416  const ID &constrainedDOF = theMP->getConstrainedDOFs();     
00417  int numCNodeDOF = myNode->getNumberDOF();
00418  int numRetainedNodeDOF = retainedDOF.Size();
00419 
00420  int loc = 0;
00421  for (int i=0; i<numCNodeDOF; i++) {
00422      if (constrainedDOF.getLocation(i) < 0) {
00423   (*modUnbalance)(loc) = responseC(i);
00424   loc++;
00425      } 
00426  }
00427  for (int j=0; j<numRetainedNodeDOF; j++) {
00428      int dof = retainedDOF(j);
00429      (*modUnbalance)(loc) = responseR(dof);
00430      loc++;
00431  }
00432  
00433  return *modUnbalance;
00434     }
00435 }
00436 
00437 // void setNodeDisp(const Vector &u);
00438 // Method to set the corresponding nodes displacements to the
00439 // values in u, components identified by myID;
00440 
00441 void
00442 TransformationDOF_Group::setNodeDisp(const Vector &u)
00443 {
00444     // call base class method and return if no MP_Constraint
00445     if (theMP == 0) {
00446  this->DOF_Group::setNodeDisp(u);
00447  return;
00448     }
00449  
00450    const ID &theID = this->getID();
00451    for (int i=0; i<modNumDOF; i++) {
00452  int loc = theID(i);
00453  if (loc >= 0)
00454      (*modUnbalance)(i) = u(loc);
00455  // DO THE SP STUFF
00456     }    
00457     Matrix *T = this->getT();
00458     if (T != 0) {
00459  *unbalance = (*T) * (*modUnbalance);
00460  myNode->setTrialDisp(*unbalance);
00461     } else
00462  myNode->setTrialDisp(*modUnbalance);
00463 }
00464 
00465 void
00466 TransformationDOF_Group::setNodeVel(const Vector &u)
00467 {
00468     // call base class method and return if no MP_Constraint
00469     if (theMP == 0) {
00470  this->DOF_Group::setNodeVel(u);
00471  return;
00472     }
00473     
00474    const ID &theID = this->getID();
00475    for (int i=0; i<modNumDOF; i++) {
00476  int loc = theID(i);
00477  if (loc >= 0)
00478      (*modUnbalance)(i) = u(loc);
00479  else  // NO SP STUFF .. WHAT TO DO
00480      (*modUnbalance)(i) = 0.0;     
00481 
00482     }    
00483     Matrix *T = this->getT();
00484     if (T != 0) {
00485  *unbalance = (*T) * (*modUnbalance);
00486  myNode->setTrialVel(*unbalance);
00487     } else
00488  myNode->setTrialVel(*modUnbalance);
00489 }
00490 
00491 
00492 void
00493 TransformationDOF_Group::setNodeAccel(const Vector &u)
00494 {
00495     // call base class method and return if no MP_Constraint
00496     if (theMP == 0) {
00497  this->DOF_Group::setNodeAccel(u);
00498  return;
00499     }
00500     
00501    const ID &theID = this->getID();
00502    for (int i=0; i<modNumDOF; i++) {
00503  int loc = theID(i);
00504  if (loc >= 0)
00505      (*modUnbalance)(i) = u(loc);
00506  else  // NO SP STUFF .. WHAT TO DO
00507      (*modUnbalance)(i) = 0.0;     
00508 
00509     }    
00510     Matrix *T = this->getT();
00511     if (T != 0) {
00512  *unbalance = (*T) * (*modUnbalance);
00513  myNode->setTrialAccel(*unbalance);
00514     } else
00515  myNode->setTrialAccel(*modUnbalance);
00516 }
00517 
00518 
00519 // void setNodeIncrDisp(const Vector &u);
00520 // Method to set the corresponding nodes displacements to the
00521 // values in u, components identified by myID;
00522 
00523 void
00524 TransformationDOF_Group::incrNodeDisp(const Vector &u)
00525 {
00526     // call base class method and return if no MP_Constraint
00527     if (theMP == 0) {
00528  this->DOF_Group::incrNodeDisp(u);
00529  return;
00530     }
00531 
00532    const ID &theID = this->getID();
00533 
00534    for (int i=0; i<modNumDOF; i++) {
00535  int loc = theID(i);
00536  if (loc >= 0)
00537      (*modUnbalance)(i) = u(loc);
00538  else  // DO THE SP STUFF
00539      (*modUnbalance)(i) = 0.0;     
00540     }    
00541 
00542     Matrix *T = this->getT();
00543     if (T != 0) {
00544  *unbalance = (*T) * (*modUnbalance);
00545  myNode->incrTrialDisp(*unbalance);
00546     } else 
00547  myNode->incrTrialDisp(*modUnbalance);
00548 }
00549  
00550 
00551 void
00552 TransformationDOF_Group::incrNodeVel(const Vector &u)
00553 {
00554     // call base class method and return if no MP_Constraint
00555     if (theMP == 0) {
00556  this->DOF_Group::incrNodeVel(u);
00557  return;
00558     }
00559     
00560    const ID &theID = this->getID();
00561    for (int i=0; i<modNumDOF; i++) {
00562  int loc = theID(i);
00563  if (loc >= 0)
00564      (*modUnbalance)(i) = u(loc);
00565  else  // DO THE SP STUFF
00566      (*modUnbalance)(i) = 0.0;     
00567     }    
00568     Matrix *T = this->getT();
00569     if (T != 0) {
00570  *unbalance = (*T) * (*modUnbalance);
00571  myNode->incrTrialVel(*unbalance);
00572     } else
00573  myNode->incrTrialVel(*modUnbalance);
00574 }
00575 
00576 
00577 void
00578 TransformationDOF_Group::incrNodeAccel(const Vector &u)
00579 {
00580     // call base class method and return if no MP_Constraint
00581     if (theMP == 0) {
00582  this->DOF_Group::incrNodeAccel(u);
00583  return;
00584     }
00585     
00586    const ID &theID = this->getID();
00587    for (int i=0; i<modNumDOF; i++) {
00588  int loc = theID(i);
00589  if (loc >= 0)
00590      (*modUnbalance)(i) = u(loc);
00591  else  // DO THE SP STUFF
00592      (*modUnbalance)(i) = 0.0;     
00593     }    
00594     Matrix *T = this->getT();
00595     if (T != 0) {
00596  *unbalance = (*T) * (*modUnbalance);
00597  myNode->incrTrialAccel(*unbalance);
00598     } else
00599  myNode->incrTrialAccel(*modUnbalance);
00600 }
00601 
00602 
00603 void
00604 TransformationDOF_Group::setEigenvector(int mode, const Vector &u)
00605 {
00606     // call base class method and return if no MP_Constraint
00607     if (theMP == 0) {
00608  this->DOF_Group::setNodeDisp(u);
00609  return;
00610     }
00611  
00612    const ID &theID = this->getID();
00613    for (int i=0; i<modNumDOF; i++) {
00614  int loc = theID(i);
00615  if (loc >= 0)
00616      (*modUnbalance)(i) = u(loc);
00617  // DO THE SP STUFF
00618     }    
00619     Matrix *T = this->getT();
00620     if (T != 0) {
00621  *unbalance = (*T) * (*modUnbalance);
00622  myNode->setEigenvector(mode, *unbalance);
00623     } else
00624  myNode->setEigenvector(mode, *modUnbalance);
00625 }
00626 
00627 
00628 Matrix *
00629 TransformationDOF_Group::getT(void)
00630 {
00631     if (theMP == 0)
00632  return 0;
00633 
00634     if (theMP->isTimeVarying() == false) {
00635  return Trans;
00636     }
00637     
00638     int numNodalDOF = this->DOF_Group::getNumDOF();
00639     // const ID &retainedDOF = theMP->getRetainedDOFs();
00640     const ID &constrainedDOF = theMP->getConstrainedDOFs();    
00641     int numNodalDOFConstrained = constrainedDOF.Size();
00642     int numRetainedDOF = numNodalDOF - numNodalDOFConstrained;
00643     //    int numReatainedNodeDOF = retainedDOF.Size();
00644 
00645     Trans->Zero();
00646     const Matrix &Ccr = theMP->getConstraint();
00647     int col = 0;
00648     for (int i=0; i<numNodalDOF; i++) {
00649  int loc = constrainedDOF.getLocation(i);
00650  if (loc < 0) {
00651      (*Trans)(i,col) = 1.0;
00652      col++;
00653  } else {
00654      for (int j=0; j<numRetainedDOF; j++)
00655   (*Trans)(i,j+numRetainedDOF) = Ccr(loc,j);
00656  } 
00657     }    
00658     return Trans;    
00659 }
00660 
00661 
00662 int
00663 TransformationDOF_Group::doneID(void)
00664 {
00665 
00666     if (theMP == 0)
00667  return 0;
00668     
00669     // get number of DOF & verify valid
00670     int numNodalDOF = this->getNumDOF();
00671     const ID &retainedDOF = theMP->getRetainedDOFs();
00672     const ID &constrainedDOF = theMP->getConstrainedDOFs();    
00673     int numNodalDOFConstrained = constrainedDOF.Size();
00674     int numRetainedDOF = numNodalDOF - numNodalDOFConstrained;
00675     int numRetainedNodeDOF = retainedDOF.Size();
00676 
00677     int retainedNode = theMP->getNodeRetained();
00678     Domain *theDomain = myNode->getDomain();
00679     Node *retainedNodePtr = theDomain->getNode(retainedNode);
00680     DOF_Group *retainedGroup = retainedNodePtr->getDOF_GroupPtr();
00681     const ID &otherID = retainedGroup->getID();
00682     
00683     // set the ID for those dof corresponding to dof at another node
00684     for (int i=0; i<numRetainedNodeDOF; i++) {
00685  int dof = retainedDOF(i);
00686  int id = otherID(dof);
00687  (*modID)(i+numRetainedDOF) = id;
00688     }
00689     
00690     // if constraint is not time-varying determine the transformation matrix
00691     if (theMP->isTimeVarying() == false) {
00692  Trans->Zero();
00693  const Matrix &Ccr = theMP->getConstraint();
00694  int col = 0;
00695  for (int i=0; i<numNodalDOF; i++) {
00696      int loc = constrainedDOF.getLocation(i);
00697      if (loc < 0) {
00698   (*Trans)(i,col) = 1.0;
00699   col++;
00700      } else {
00701   for (int j=0; j<numRetainedNodeDOF; j++)
00702       (*Trans)(i,j+numRetainedDOF) = Ccr(loc,j);
00703      }
00704  }
00705     }
00706  
00707     // set the pointers for the tangent and residual
00708     if (modNumDOF <= MAX_NUM_DOF) {
00709  // use class wide objects
00710  if (modVectors[modNumDOF] == 0) {
00711      // have to create matrix and vector of size as none yet created
00712      modVectors[modNumDOF] = new Vector(modNumDOF);
00713      modMatrices[modNumDOF] = new Matrix(modNumDOF,modNumDOF);
00714      modUnbalance = modVectors[modNumDOF];
00715      modTangent = modMatrices[modNumDOF];
00716      if (modUnbalance == 0 || modUnbalance->Size() != modNumDOF || 
00717   modTangent == 0 || modTangent->noCols() != modNumDOF) {  
00718   cerr << "DOF_Group::DOF_Group(Node *) ";
00719   cerr << " ran out of memory for vector/Matrix of size :";
00720   cerr << modNumDOF << endl;
00721   exit(-1);
00722      }
00723  } else {
00724      modUnbalance = modVectors[modNumDOF];
00725      modTangent = modMatrices[modNumDOF];
00726  }
00727     } else {
00728  // create matrices and vectors for each object instance
00729  modUnbalance = new Vector(modNumDOF);
00730  modTangent = new Matrix(modNumDOF, modNumDOF);
00731  if (modUnbalance == 0 || modUnbalance->Size() ==0 ||
00732      modTangent ==0 || modTangent->noRows() ==0) {
00733      
00734      cerr << "DOF_Group::DOF_Group(Node *) ";
00735      cerr << " ran out of memory for vector/Matrix of size :";
00736      cerr << modNumDOF << endl;
00737      exit(-1);
00738  }
00739     }    
00740     return 0;
00741 }
00742 
00743 int 
00744 TransformationDOF_Group::addSP_Constraint(SP_Constraint &theSP)
00745 {
00746     // add the SP_Constraint
00747     int dof = theSP.getDOF_Number();
00748     theSPs[dof] = &theSP;
00749 
00750     // set a -1 in the correct ID location
00751     if (theMP == 0)
00752  this->setID(dof,-1);
00753     else {
00754  const ID &constrainedDOF = theMP->getConstrainedDOFs();
00755  int loc = 0;
00756  for (int i=0; i<dof; i++) 
00757      if (constrainedDOF.getLocation(i) < 0)
00758   loc++;
00759  this->setID(loc,-1);
00760     } 
00761     return 0;
00762 }
00763 
00764 int 
00765 TransformationDOF_Group::enforceSPs(void)
00766 {
00767     Vector trialDisp(myNode->getTrialDisp());
00768     int numDof = myNode->getNumberDOF();
00769     for (int i=0; i<numDof; i++)
00770  if (theSPs[i] != 0) {
00771      double value = theSPs[i]->getValue();
00772      trialDisp(i) = value;
00773  }
00774     myNode->setTrialDisp(trialDisp);
00775     
00776     return 0;
00777 }
00778 
00779 void
00780 TransformationDOF_Group::addM_Force(const Vector &Udotdot, double fact)
00781 {
00782     // call base class method and return if no MP_Constraint
00783     if (theMP == 0 || modID == 0) {
00784  this->DOF_Group::addM_Force(Udotdot, fact);
00785  return;
00786     }
00787     
00788    for (int i=0; i<modNumDOF; i++) {
00789  int loc = (*modID)(i);
00790  if (loc >= 0)
00791      (*modUnbalance)(i) = Udotdot(loc);
00792  else  // DO THE SP STUFF
00793      (*modUnbalance)(i) = 0.0;     
00794     }    
00795 
00796     Vector unmod(Trans->noRows());
00797     unmod = (*Trans) * (*modUnbalance);
00798     this->addLocalM_Force(unmod,fact);
00799 }
Copyright Contact Us