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.16 $
00022 // $Date: 2005/11/29 23:31:10 $
00023 // $Source: /usr/local/cvs/OpenSees/SRC/analysis/dof_grp/TransformationDOF_Group.cpp,v $
00024                                                                         
00025                                                                         
00026 // Written: fmk 
00027 // Created: 05/99
00028 // Revision: A
00029 //
00030 // Purpose: This file contains the code for implementing the methods
00031 // of the TransformationDOF_Group class interface.
00032 //
00033 // What: "@(#) TransformationDOF_Group.C, revA"
00034 
00035 #include <TransformationDOF_Group.h>
00036 #include <stdlib.h>
00037 
00038 #include <Domain.h>
00039 #include <Node.h>
00040 #include <Vector.h>
00041 #include <Matrix.h>
00042 #include <TransientIntegrator.h>
00043 #include <MP_Constraint.h>
00044 #include <SP_Constraint.h>
00045 #include <SP_ConstraintIter.h>
00046 #include <TransformationConstraintHandler.h>
00047 
00048 #define MAX_NUM_DOF 16
00049 
00050 // static variables initialisation
00051 Matrix **TransformationDOF_Group::modMatrices; 
00052 Vector **TransformationDOF_Group::modVectors;  
00053 int TransformationDOF_Group::numTransDOFs(0);     // number of objects
00054 TransformationConstraintHandler *TransformationDOF_Group::theHandler = 0;     // number of objects
00055 
00056 TransformationDOF_Group::TransformationDOF_Group(int tag, Node *node, 
00057                                                  MP_Constraint *mp,
00058                                                  TransformationConstraintHandler *theTHandler)  
00059 :DOF_Group(tag,node),
00060  theMP(mp),Trans(0),modTangent(0),modUnbalance(0),modID(0),theSPs(0)
00061 {
00062     // determine the number of DOF 
00063     int numNodalDOF = node->getNumberDOF();
00064     const ID &retainedDOF = mp->getRetainedDOFs();
00065     const ID &constrainedDOF = mp->getConstrainedDOFs();    
00066     int numNodalDOFConstrained = constrainedDOF.Size();
00067     int numConstrainedNodeRetainedDOF = numNodalDOF - numNodalDOFConstrained;
00068     int numRetainedNodeDOF = retainedDOF.Size();
00069 
00070     modNumDOF = numConstrainedNodeRetainedDOF + numRetainedNodeDOF;
00071 
00072     // create space for the SP_Constraint array
00073     theSPs = new SP_Constraint *[numNodalDOF];
00074     for (int ii=0; ii<numNodalDOF; ii++) 
00075         theSPs[ii] = 0;
00076 
00077     /***********************
00078     // set the SP_Constraint corresponding to the dof in modID
00079     Domain *theDomain=node->getDomain();
00080     int nodeTag = node->getTag();    
00081     SP_ConstraintIter &theSPIter = theDomain->getSPs();
00082     SP_Constraint *sp;
00083     while ((sp = theSPIter()) != 0) {
00084         if (sp->getNodeTag() == nodeTag) {
00085             int dof = sp->getDOF_Number();
00086             int loc = 0;
00087             for (int i=0; i<dof; i++) 
00088                 if (constrainedDOF.getLocation(i) < 0)
00089                     loc++;
00090             theSPs[loc] = sp;
00091         }
00092     }
00093     *******************/
00094      
00095     // create ID and transformation matrix
00096     modID = new ID(modNumDOF);
00097     Trans = new Matrix(numNodalDOF, modNumDOF);
00098 
00099     if (modID == 0 || modID->Size() == 0 ||
00100         Trans == 0 || Trans->noRows() == 0) {
00101         
00102         opserr << "FATAL TransformationDOF_Group::TransformationDOF_Group() -";
00103         opserr << " ran out of memory for size: " << modNumDOF << endln;
00104         exit(-1);
00105     }
00106 
00107     // initially set the id values to -2 for any dof still due to constrained node
00108     for (int i=0; i<numConstrainedNodeRetainedDOF; i++)
00109         (*modID)(i) = -2;
00110     
00111     // for all the constrained dof values set to -1
00112     for (int j=numConstrainedNodeRetainedDOF; j<modNumDOF; j++)
00113         (*modID)(j) = -1;
00114 
00115     // for all the dof corresponding to the retained node set initially to -1
00116     // we don't initially assign these equation nos. - this is done in doneID()
00117     for (int k=numConstrainedNodeRetainedDOF; k<modNumDOF; k++)
00118         (*modID)(k) = -1;
00119     
00120     // if this is the first TransformationDOF_Group we now
00121     // create the arrays used to store pointers to class wide
00122     // matrix and vector objects used to return modTangent and residual
00123     if (numTransDOFs == 0) {
00124         modMatrices = new Matrix *[MAX_NUM_DOF+1];
00125         modVectors  = new Vector *[MAX_NUM_DOF+1];
00126         
00127         if (modMatrices == 0 || modVectors == 0) {
00128             opserr << "TransformationDOF_Group::TransformationDOF_Group(Node *) ";
00129             opserr << " ran out of memory";         
00130         }
00131         for (int i=0; i<MAX_NUM_DOF; i++) {
00132             modMatrices[i] = 0;
00133             modVectors[i] = 0;
00134         }
00135     }    
00136 
00137     // set the pointers for the modTangent and residual
00138     if (modNumDOF <= MAX_NUM_DOF) {
00139         // use class wide objects
00140         if (modVectors[modNumDOF] == 0) {
00141             // have to create matrix and vector of size as none yet created
00142             modVectors[modNumDOF] = new Vector(modNumDOF);
00143             modMatrices[modNumDOF] = new Matrix(modNumDOF,modNumDOF);
00144             modUnbalance = modVectors[modNumDOF];
00145             modTangent = modMatrices[modNumDOF];
00146             if (modUnbalance == 0 || modUnbalance->Size() != modNumDOF ||       
00147                 modTangent == 0 || modTangent->noCols() != modNumDOF)   {  
00148                 opserr << "TransformationDOF_Group::TransformationDOF_Group(Node *) ";
00149                 opserr << " ran out of memory for vector/Matrix of size :";
00150                 opserr << modNumDOF << endln;
00151                 exit(-1);
00152             }
00153         } else {
00154             modUnbalance = modVectors[modNumDOF];
00155             modTangent = modMatrices[modNumDOF];
00156         }
00157     } else {
00158         // create matrices and vectors for each object instance
00159         modUnbalance = new Vector(modNumDOF);
00160         modTangent = new Matrix(modNumDOF, modNumDOF);
00161         if (modUnbalance == 0 || modTangent ==0 ||
00162             modTangent ==0 || modTangent->noRows() ==0) {
00163             
00164             opserr << "TransformationDOF_Group::TransformationDOF_Group(Node *) ";
00165             opserr << " ran out of memory for vector/Matrix of size :";
00166             opserr << modNumDOF << endln;
00167             exit(-1);
00168         }
00169     }
00170     
00171     numTransDOFs++;
00172     theHandler = theTHandler;
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, 
00186                                                  Node *node, 
00187                                                  TransformationConstraintHandler *theTHandler)
00188 :DOF_Group(tag,node),
00189  theMP(0),Trans(0),modTangent(0),modUnbalance(0),modID(0),theSPs(0) 
00190 {
00191     modNumDOF = node->getNumberDOF();
00192     // create space for the SP_Constraint array
00193     theSPs = new SP_Constraint *[modNumDOF];
00194     for (int i=0; i<modNumDOF; i++) 
00195         theSPs[i] = 0;
00196 
00197     // set the SP_Constraint corresponding to the dof in myID
00198     Domain *theDomain=node->getDomain();
00199     int nodeTag = node->getTag();
00200     SP_ConstraintIter &theSPIter = theDomain->getSPs();
00201     SP_Constraint *sp;
00202     while ((sp = theSPIter()) != 0) {
00203         if (sp->getNodeTag() == nodeTag) {
00204             int dof = sp->getDOF_Number();
00205             theSPs[dof] = sp;
00206         }
00207     }    
00208     
00209     // if this is the first TransformationDOF_Group we now
00210     // create the arrays used to store pointers to class wide
00211     // matrix and vector objects used to return modTangent and residual
00212     if (numTransDOFs == 0) {
00213         modMatrices = new Matrix *[MAX_NUM_DOF+1];
00214         modVectors  = new Vector *[MAX_NUM_DOF+1];
00215         
00216         if (modMatrices == 0 || modVectors == 0) {
00217             opserr << "TransformationDOF_Group::TransformationDOF_Group(Node *) ";
00218             opserr << " ran out of memory";         
00219         }
00220         for (int i=0; i<MAX_NUM_DOF; i++) {
00221             modMatrices[i] = 0;
00222             modVectors[i] = 0;
00223         }
00224     }    
00225 
00226     numTransDOFs++;
00227     theHandler = theTHandler;
00228 }
00229 
00230 
00231 // ~TransformationDOF_Group();    
00232 //      destructor.
00233 
00234 TransformationDOF_Group::~TransformationDOF_Group()
00235 {
00236     numTransDOFs--;
00237 
00238     // delete modTangent and residual if created specially
00239     if (modNumDOF > MAX_NUM_DOF) {
00240         if (modTangent != 0) delete modTangent;
00241         if (modUnbalance != 0) delete modUnbalance;
00242     }
00243     
00244     if (modID != 0) delete modID;
00245     if (Trans != 0) delete Trans;
00246     if (theSPs != 0) delete [] theSPs;
00247 
00248     // if this is the last FE_Element, clean up the
00249     // storage for the matrix and vector objects
00250     if (numTransDOFs == 0) {
00251         for (int i=0; i<MAX_NUM_DOF; i++) {
00252             if (modVectors[i] != 0)
00253                 delete modVectors[i];
00254             if (modMatrices[i] != 0)
00255                 delete modMatrices[i];
00256         }       
00257         delete [] modMatrices;
00258         delete [] modVectors;
00259     }    
00260 }    
00261 
00262 
00263 const ID &
00264 TransformationDOF_Group::getID(void) const
00265 {
00266     if (modID != 0)
00267         return *modID;
00268     else
00269         return this->DOF_Group::getID();
00270 }
00271 
00272 int
00273 TransformationDOF_Group::getNumDOF(void) const
00274 {
00275     return modNumDOF;
00276 }
00277 
00278 
00279 int
00280 TransformationDOF_Group::getNumFreeDOF(void) const
00281 {
00282     if (modID != 0) {
00283         int numFreeDOF = modNumDOF;
00284         for (int i=0; i<modNumDOF; i++)
00285             if ((*modID)(i) == -1)
00286                 numFreeDOF--;
00287         return numFreeDOF;      
00288     } else
00289         return this->DOF_Group::getNumFreeDOF();
00290 }
00291 
00292 int
00293 TransformationDOF_Group::getNumConstrainedDOF(void) const
00294 {   
00295     if (modID != 0) {    
00296         int numConstr = 0;
00297         for (int i=0; i<modNumDOF; i++)
00298             if ((*modID)(i) < 0)
00299                 numConstr++;    
00300         
00301         return numConstr;
00302     } else
00303         return this->DOF_Group::getNumConstrainedDOF(); 
00304 }    
00305 
00306 
00307 
00308 const Matrix &
00309 TransformationDOF_Group::getTangent(Integrator *theIntegrator) 
00310 {
00311 
00312 
00313     const Matrix &unmodTangent = this->DOF_Group::getTangent(theIntegrator);
00314     Matrix *T = this->getT();
00315     if (T != 0) {
00316         // *modTangent = (*T) ^ unmodTangent * (*T);
00317         modTangent->addMatrixTripleProduct(0.0, *T, unmodTangent, 1.0);
00318         return *modTangent;
00319         
00320     } else 
00321       return unmodTangent;
00322 }
00323 
00324 const Vector &
00325 TransformationDOF_Group::getUnbalance(Integrator *theIntegrator)
00326 {
00327     const Vector &unmodUnbalance = 
00328         this->DOF_Group::getUnbalance(theIntegrator);
00329 
00330     Matrix *T = this->getT();
00331     if (T != 0) {
00332         // *modUnbalance = (*T) ^ unmodUnbalance;
00333         modUnbalance->addMatrixTransposeVector(0.0, *T, unmodUnbalance, 1.0);
00334         return *modUnbalance;    
00335     } else
00336         return unmodUnbalance;
00337 }
00338 
00339 
00340 const Vector & 
00341 TransformationDOF_Group::getCommittedDisp(void)
00342 {
00343     const Vector &responseC = myNode->getDisp();
00344     
00345     if (theMP == 0)
00346         return responseC;
00347     else {
00348         int retainedNode = theMP->getNodeRetained();
00349         Domain *theDomain = myNode->getDomain();
00350         Node *retainedNodePtr = theDomain->getNode(retainedNode);
00351         const Vector &responseR = retainedNodePtr->getDisp();
00352         const ID &retainedDOF = theMP->getRetainedDOFs();
00353         const ID &constrainedDOF = theMP->getConstrainedDOFs();         
00354         int numCNodeDOF = myNode->getNumberDOF();
00355         int numRetainedNodeDOF = retainedDOF.Size();
00356 
00357         int loc = 0;
00358         for (int i=0; i<numCNodeDOF; i++) {
00359             if (constrainedDOF.getLocation(i) < 0) {
00360                 (*modUnbalance)(loc) = responseC(i);
00361                 loc++;
00362             } 
00363         }
00364         for (int j=0; j<numRetainedNodeDOF; j++) {
00365             int dof = retainedDOF(j);
00366             (*modUnbalance)(loc) = responseR(dof);
00367             loc++;
00368         }
00369 
00370         return *modUnbalance;
00371     }
00372 }
00373 
00374 const Vector & 
00375 TransformationDOF_Group::getCommittedVel(void)
00376 {
00377     const Vector &responseC = myNode->getVel();
00378     
00379     if (theMP == 0)
00380         return responseC;
00381     else {
00382         int retainedNode = theMP->getNodeRetained();
00383         Domain *theDomain = myNode->getDomain();
00384         Node *retainedNodePtr = theDomain->getNode(retainedNode);
00385         const Vector &responseR = retainedNodePtr->getVel();
00386         const ID &retainedDOF = theMP->getRetainedDOFs();
00387         const ID &constrainedDOF = theMP->getConstrainedDOFs();         
00388         int numCNodeDOF = myNode->getNumberDOF();
00389         int numRetainedNodeDOF = retainedDOF.Size();
00390 
00391         int loc = 0;
00392         for (int i=0; i<numCNodeDOF; i++) {
00393             if (constrainedDOF.getLocation(i) < 0) {
00394                 (*modUnbalance)(loc) = responseC(i);
00395                 loc++;
00396             } 
00397         }
00398         for (int j=0; j<numRetainedNodeDOF; j++) {
00399             int dof = retainedDOF(j);
00400             (*modUnbalance)(loc) = responseR(dof);
00401             loc++;
00402         }
00403         
00404         return *modUnbalance;
00405     }
00406 }
00407 
00408 
00409 const Vector & 
00410 TransformationDOF_Group::getCommittedAccel(void)
00411 {
00412     const Vector &responseC = myNode->getAccel();
00413     
00414     if (theMP == 0)
00415         return responseC;
00416     else {
00417         int retainedNode = theMP->getNodeRetained();
00418         Domain *theDomain = myNode->getDomain();
00419         Node *retainedNodePtr = theDomain->getNode(retainedNode);
00420         const Vector &responseR = retainedNodePtr->getAccel();
00421         const ID &retainedDOF = theMP->getRetainedDOFs();
00422         const ID &constrainedDOF = theMP->getConstrainedDOFs();         
00423         int numCNodeDOF = myNode->getNumberDOF();
00424         int numRetainedNodeDOF = retainedDOF.Size();
00425 
00426         int loc = 0;
00427         for (int i=0; i<numCNodeDOF; i++) {
00428             if (constrainedDOF.getLocation(i) < 0) {
00429                 (*modUnbalance)(loc) = responseC(i);
00430                 loc++;
00431             } 
00432         }
00433         for (int j=0; j<numRetainedNodeDOF; j++) {
00434             int dof = retainedDOF(j);
00435             (*modUnbalance)(loc) = responseR(dof);
00436             loc++;
00437         }
00438         
00439         return *modUnbalance;
00440     }
00441 }
00442 
00443 // void setNodeDisp(const Vector &u);
00444 //      Method to set the corresponding nodes displacements to the
00445 //      values in u, components identified by myID;
00446 
00447 void
00448 TransformationDOF_Group::setNodeDisp(const Vector &u)
00449 {
00450   // call base class method and return if no MP_Constraint
00451   if (theMP == 0) {
00452     this->DOF_Group::setNodeDisp(u);
00453     return;
00454   }
00455 
00456    const ID &theID = this->getID();
00457    for (int i=0; i<modNumDOF; i++) {
00458         int loc = theID(i);
00459         if (loc >= 0)
00460             (*modUnbalance)(i) = u(loc);
00461         else
00462             (*modUnbalance)(i) = 0.0;
00463           
00464 
00465     }    
00466     Matrix *T = this->getT();
00467     if (T != 0) {
00468 
00469         // *unbalance = (*T) * (*modUnbalance);
00470         unbalance->addMatrixVector(0.0, *T, *modUnbalance, 1.0);
00471         myNode->setTrialDisp(*unbalance);
00472 
00473     } else
00474         myNode->setTrialDisp(*modUnbalance);
00475 }
00476 
00477 void
00478 TransformationDOF_Group::setNodeVel(const Vector &u)
00479 {
00480     // call base class method and return if no MP_Constraint
00481     if (theMP == 0) {
00482         this->DOF_Group::setNodeVel(u);
00483         return;
00484     }
00485     
00486    const ID &theID = this->getID();
00487    for (int i=0; i<modNumDOF; i++) {
00488         int loc = theID(i);
00489         if (loc >= 0)
00490             (*modUnbalance)(i) = u(loc);
00491         else    // NO SP STUFF .. WHAT TO DO
00492             (*modUnbalance)(i) = 0.0;       
00493 
00494     }    
00495     Matrix *T = this->getT();
00496     if (T != 0) {
00497         // *unbalance = (*T) * (*modUnbalance);
00498         unbalance->addMatrixVector(0.0, *T, *modUnbalance, 1.0);
00499         myNode->setTrialVel(*unbalance);
00500     } else
00501         myNode->setTrialVel(*modUnbalance);
00502 }
00503 
00504 
00505 void
00506 TransformationDOF_Group::setNodeAccel(const Vector &u)
00507 {
00508     // call base class method and return if no MP_Constraint
00509     if (theMP == 0) {
00510         this->DOF_Group::setNodeAccel(u);
00511         return;
00512     }
00513     
00514    const ID &theID = this->getID();
00515    for (int i=0; i<modNumDOF; i++) {
00516         int loc = theID(i);
00517         if (loc >= 0)
00518             (*modUnbalance)(i) = u(loc);
00519         else    // NO SP STUFF .. WHAT TO DO
00520             (*modUnbalance)(i) = 0.0;       
00521 
00522     }    
00523     Matrix *T = this->getT();
00524     if (T != 0) {
00525         // *unbalance = (*T) * (*modUnbalance);
00526         unbalance->addMatrixVector(0.0, *T, *modUnbalance, 1.0);
00527         myNode->setTrialAccel(*unbalance);
00528     } else
00529         myNode->setTrialAccel(*modUnbalance);
00530 }
00531 
00532 
00533 // void setNodeIncrDisp(const Vector &u);
00534 //      Method to set the corresponding nodes displacements to the
00535 //      values in u, components identified by myID;
00536 
00537 void
00538 TransformationDOF_Group::incrNodeDisp(const Vector &u)
00539 {
00540     // call base class method and return if no MP_Constraint
00541     if (theMP == 0) {
00542         this->DOF_Group::incrNodeDisp(u);
00543         return;
00544     }
00545 
00546    const ID &theID = this->getID();
00547 
00548    for (int i=0; i<modNumDOF; i++) {
00549         int loc = theID(i);
00550         if (loc >= 0)
00551             (*modUnbalance)(i) = u(loc);
00552         else    // DO THE SP STUFF
00553             (*modUnbalance)(i) = 0.0;       
00554     }    
00555 
00556     Matrix *T = this->getT();
00557     if (T != 0) {
00558         // *unbalance = (*T) * (*modUnbalance);
00559         unbalance->addMatrixVector(0.0, *T, *modUnbalance, 1.0);
00560         myNode->incrTrialDisp(*unbalance);
00561     } else 
00562         myNode->incrTrialDisp(*modUnbalance);
00563 }
00564         
00565 
00566 void
00567 TransformationDOF_Group::incrNodeVel(const Vector &u)
00568 {
00569     // call base class method and return if no MP_Constraint
00570     if (theMP == 0) {
00571         this->DOF_Group::incrNodeVel(u);
00572         return;
00573     }
00574     
00575    const ID &theID = this->getID();
00576    for (int i=0; i<modNumDOF; i++) {
00577         int loc = theID(i);
00578         if (loc >= 0)
00579             (*modUnbalance)(i) = u(loc);
00580         else    // DO THE SP STUFF
00581             (*modUnbalance)(i) = 0.0;       
00582     }    
00583     Matrix *T = this->getT();
00584     if (T != 0) {
00585         // *unbalance = (*T) * (*modUnbalance);
00586         unbalance->addMatrixVector(0.0, *T, *modUnbalance, 1.0);
00587         myNode->incrTrialVel(*unbalance);
00588     } else
00589         myNode->incrTrialVel(*modUnbalance);
00590 }
00591 
00592 
00593 void
00594 TransformationDOF_Group::incrNodeAccel(const Vector &u)
00595 {
00596     // call base class method and return if no MP_Constraint
00597     if (theMP == 0) {
00598         this->DOF_Group::incrNodeAccel(u);
00599         return;
00600     }
00601     
00602    const ID &theID = this->getID();
00603    for (int i=0; i<modNumDOF; i++) {
00604         int loc = theID(i);
00605         if (loc >= 0)
00606             (*modUnbalance)(i) = u(loc);
00607         else    // DO THE SP STUFF
00608             (*modUnbalance)(i) = 0.0;       
00609     }    
00610     Matrix *T = this->getT();
00611     if (T != 0) {
00612         // *unbalance = (*T) * (*modUnbalance);
00613         unbalance->addMatrixVector(0.0, *T, *modUnbalance, 1.0);
00614         myNode->incrTrialAccel(*unbalance);
00615     } else
00616         myNode->incrTrialAccel(*modUnbalance);
00617 }
00618 
00619 
00620 void
00621 TransformationDOF_Group::setEigenvector(int mode, const Vector &u)
00622 {
00623     // call base class method and return if no MP_Constraint
00624     if (theMP == 0) {
00625         this->DOF_Group::setEigenvector(mode, u);
00626         return;
00627     }
00628         
00629    const ID &theID = this->getID();
00630    for (int i=0; i<modNumDOF; i++) {
00631         int loc = theID(i);
00632         if (loc >= 0)
00633             (*modUnbalance)(i) = u(loc);
00634         // DO THE SP STUFF
00635     }    
00636     Matrix *T = this->getT();
00637     if (T != 0) {
00638         // *unbalance = (*T) * (*modUnbalance);
00639         unbalance->addMatrixVector(0.0, *T, *modUnbalance, 1.0);
00640         myNode->setEigenvector(mode, *unbalance);
00641     } else
00642         myNode->setEigenvector(mode, *modUnbalance);
00643 }
00644 
00645 
00646 Matrix *
00647 TransformationDOF_Group::getT(void)
00648 {
00649     if (theMP == 0)
00650         return 0;
00651 
00652     if (theMP->isTimeVarying() == false) {
00653         return Trans;
00654     }
00655     
00656     int numNodalDOF = myNode->getNumberDOF();
00657     const ID &retainedDOF = theMP->getRetainedDOFs();
00658     const ID &constrainedDOF = theMP->getConstrainedDOFs();    
00659     int numNodalDOFConstrained = constrainedDOF.Size();
00660     int numRetainedDOF = numNodalDOF - numNodalDOFConstrained;
00661     int numRetainedNodeDOF = retainedDOF.Size();
00662 
00663     Trans->Zero();
00664     const Matrix &Ccr = theMP->getConstraint();
00665     int col = 0;
00666     for (int i=0; i<numNodalDOF; i++) {
00667       int loc = constrainedDOF.getLocation(i);
00668       if (loc < 0) {
00669         (*Trans)(i,col) = 1.0;
00670         col++;
00671       } else {
00672         for (int j=0; j<numRetainedNodeDOF; j++)
00673           (*Trans)(i,j+numRetainedDOF) = Ccr(loc,j);
00674       }
00675     }
00676 
00677     return Trans;    
00678 }
00679 
00680 
00681 int
00682 TransformationDOF_Group::doneID(void)
00683 {
00684 
00685     if (theMP == 0)
00686         return 0;
00687     
00688     // get number of DOF & verify valid
00689     int numNodalDOF = myNode->getNumberDOF();
00690     const ID &retainedDOF = theMP->getRetainedDOFs();
00691     const ID &constrainedDOF = theMP->getConstrainedDOFs();    
00692     int numNodalDOFConstrained = constrainedDOF.Size();
00693     int numRetainedDOF = numNodalDOF - numNodalDOFConstrained;
00694     int numRetainedNodeDOF = retainedDOF.Size();
00695 
00696     int retainedNode = theMP->getNodeRetained();
00697     Domain *theDomain = myNode->getDomain();
00698     Node *retainedNodePtr = theDomain->getNode(retainedNode);
00699     DOF_Group *retainedGroup = retainedNodePtr->getDOF_GroupPtr();
00700     const ID &otherID = retainedGroup->getID();
00701     
00702     // set the ID for those dof corresponding to dof at another node
00703     for (int i=0; i<numRetainedNodeDOF; i++) {
00704         int dof = retainedDOF(i);
00705         int id = otherID(dof);
00706         (*modID)(i+numRetainedDOF) = id;
00707     }
00708     
00709     // if constraint is not time-varying determine the transformation matrix
00710     if (theMP->isTimeVarying() == false) {
00711         Trans->Zero();
00712         const Matrix &Ccr = theMP->getConstraint();
00713         int col = 0;
00714         for (int i=0; i<numNodalDOF; i++) {
00715             int loc = constrainedDOF.getLocation(i);
00716             if (loc < 0) {
00717                 (*Trans)(i,col) = 1.0;
00718                 col++;
00719             } else {
00720                 for (int j=0; j<numRetainedNodeDOF; j++)
00721                     (*Trans)(i,j+numRetainedDOF) = Ccr(loc,j);
00722             }
00723         }
00724     }
00725         
00726     // set the pointers for the tangent and residual
00727     if (modNumDOF <= MAX_NUM_DOF) {
00728         // use class wide objects
00729         if (modVectors[modNumDOF] == 0) {
00730             // have to create matrix and vector of size as none yet created
00731             modVectors[modNumDOF] = new Vector(modNumDOF);
00732             modMatrices[modNumDOF] = new Matrix(modNumDOF,modNumDOF);
00733             modUnbalance = modVectors[modNumDOF];
00734             modTangent = modMatrices[modNumDOF];
00735             if (modUnbalance == 0 || modUnbalance->Size() != modNumDOF ||       
00736                 modTangent == 0 || modTangent->noCols() != modNumDOF)   {  
00737                 opserr << "DOF_Group::DOF_Group(Node *) ";
00738                 opserr << " ran out of memory for vector/Matrix of size :";
00739                 opserr << modNumDOF << endln;
00740                 exit(-1);
00741             }
00742         } else {
00743             modUnbalance = modVectors[modNumDOF];
00744             modTangent = modMatrices[modNumDOF];
00745         }
00746     } else {
00747         // create matrices and vectors for each object instance
00748         modUnbalance = new Vector(modNumDOF);
00749         modTangent = new Matrix(modNumDOF, modNumDOF);
00750         if (modUnbalance == 0 || modUnbalance->Size() ==0 ||
00751             modTangent ==0 || modTangent->noRows() ==0) {
00752             
00753             opserr << "DOF_Group::DOF_Group(Node *) ";
00754             opserr << " ran out of memory for vector/Matrix of size :";
00755             opserr << modNumDOF << endln;
00756             exit(-1);
00757         }
00758     }    
00759     return 0;
00760 }
00761 
00762 int 
00763 TransformationDOF_Group::addSP_Constraint(SP_Constraint &theSP)
00764 {
00765     // add the SP_Constraint
00766     int dof = theSP.getDOF_Number();
00767     theSPs[dof] = &theSP;
00768 
00769     // set a -1 in the correct ID location
00770     if (theMP == 0)
00771         this->setID(dof,-1);
00772     else {
00773         const ID &constrainedDOF = theMP->getConstrainedDOFs();
00774         int loc = 0;
00775         for (int i=0; i<dof; i++) 
00776             if (constrainedDOF.getLocation(i) < 0)
00777                 loc++;
00778         this->setID(loc,-1);
00779     } 
00780     return 0;
00781 }
00782 
00783 int 
00784 TransformationDOF_Group::enforceSPs(void)
00785 {
00786   int numDof = myNode->getNumberDOF();
00787   for (int i=0; i<numDof; i++)
00788     if (theSPs[i] != 0) {
00789       double value = theSPs[i]->getValue();
00790       myNode->setTrialDisp(value, i);
00791     }
00792   
00793   return 0;
00794 }
00795 
00796 void
00797 TransformationDOF_Group::addM_Force(const Vector &Udotdot, double fact)
00798 {
00799     // call base class method and return if no MP_Constraint
00800     if (theMP == 0 || modID == 0) {
00801         this->DOF_Group::addM_Force(Udotdot, fact);
00802         return;
00803     }
00804     
00805    for (int i=0; i<modNumDOF; i++) {
00806         int loc = (*modID)(i);
00807         if (loc >= 0)
00808             (*modUnbalance)(i) = Udotdot(loc);
00809         else    // DO THE SP STUFF
00810             (*modUnbalance)(i) = 0.0;       
00811     }    
00812 
00813     Vector unmod(Trans->noRows());
00814     //unmod = (*Trans) * (*modUnbalance);
00815     unmod.addMatrixVector(0.0, *Trans, *modUnbalance, 1.0);
00816     this->addLocalM_Force(unmod, fact);
00817 }
00818 
00819 
00820 const Vector &
00821 TransformationDOF_Group::getM_Force(const Vector &Udotdot, double fact)
00822 {
00823   // call base class method and return if no MP_Constraint
00824   if (theMP == 0 || modID == 0) {
00825     return this->DOF_Group::getM_Force(Udotdot, fact);
00826   }
00827 
00828   this->DOF_Group::zeroTangent();    
00829   this->DOF_Group::addMtoTang();    
00830   const Matrix &unmodTangent = this->DOF_Group::getTangent(0);
00831 
00832     
00833   Vector data(modNumDOF);
00834   for (int i=0; i<modNumDOF; i++) {
00835     int loc = (*modID)(i);
00836     if (loc >= 0)
00837       data(i) = Udotdot(loc);
00838     else        // DO THE SP STUFF
00839       data(i) = 0.0;        
00840   }    
00841 
00842   Matrix *T = this->getT();
00843   if (T != 0) {
00844     // *modTangent = (*T) ^ unmodTangent * (*T);
00845     modTangent->addMatrixTripleProduct(0.0, *T, unmodTangent, 1.0);
00846     modUnbalance->addMatrixVector(0.0, *modTangent, data, 1.0);
00847     
00848     return *modUnbalance;
00849   } else {
00850       modUnbalance->addMatrixVector(0.0, unmodTangent, data, 1.0);
00851       return *modUnbalance;
00852   }
00853 }
00854 
00855 const Vector &
00856 TransformationDOF_Group::getC_Force(const Vector &Udotdot, double fact)
00857 {
00858   opserr << "TransformationDOF_Group::getC_Force() - not yet implemented\n";
00859   return *modUnbalance;
00860 }
00861 
00862 const Vector &
00863 TransformationDOF_Group::getTangForce(const Vector &Udotdot, double fact)
00864 {
00865   opserr << "TransformationDOF_Group::getTangForce() - not yet implemented\n";
00866   return *modUnbalance;
00867 }
00868 
00869 
00870 
00871 // AddingSensitivity:BEGIN ////////////////////////////////////////
00872 const Vector &
00873 TransformationDOF_Group::getDispSensitivity(int gradNumber)
00874 {
00875   const Vector &result = this->DOF_Group::getDispSensitivity(gradNumber);
00876 
00877   Matrix *T = this->getT();
00878   if (T != 0) {
00879     // *modUnbalance = (*T) ^ unmodUnbalance;
00880     modUnbalance->addMatrixTransposeVector(0.0, *T, result, 1.0);
00881     return *modUnbalance;    
00882   } else
00883     return result;
00884 
00885 }
00886 
00887 const Vector &
00888 TransformationDOF_Group::getVelSensitivity(int gradNumber)
00889 {
00890   const Vector &result = this->DOF_Group::getVelSensitivity(gradNumber);
00891 
00892   Matrix *T = this->getT();
00893   if (T != 0) {
00894     // *modUnbalance = (*T) ^ unmodUnbalance;
00895     modUnbalance->addMatrixTransposeVector(0.0, *T, result, 1.0);
00896     return *modUnbalance;    
00897   } else
00898     return result;
00899 }
00900 
00901 const Vector &
00902 TransformationDOF_Group::getAccSensitivity(int gradNumber)
00903 {
00904   const Vector &result = this->DOF_Group::getAccSensitivity(gradNumber);
00905 
00906   Matrix *T = this->getT();
00907   if (T != 0) {
00908     // *modUnbalance = (*T) ^ unmodUnbalance;
00909     modUnbalance->addMatrixTransposeVector(0.0, *T, result, 1.0);
00910     return *modUnbalance;    
00911   } else
00912     return result;
00913 }
00914         
00915         
00916 
00917 int 
00918 TransformationDOF_Group::saveSensitivity(Vector *u,Vector *udot,Vector *udotdot, int gradNum,int numGrads)
00919 {
00920   // call base class method and return if no MP_Constraint
00921   if (theMP == 0) {
00922     return this->DOF_Group::saveSensitivity(u, udot, udotdot, gradNum, numGrads);
00923   }
00924   
00925   // Get sensitivities for my dof out of vectors
00926   Vector *myV = new Vector(modNumDOF);
00927   Vector *myVdot = 0;
00928   Vector *myVdotdot = 0;
00929 
00930   
00931         
00932   const ID &theID = this->getID();
00933   for (int i=0; i<modNumDOF; i++) {
00934     int loc = theID(i);
00935     if (loc >= 0)
00936       (*modUnbalance)(i) = (*u)(loc);
00937     // DO THE SP STUFF
00938   }    
00939   Matrix *T = this->getT();
00940   if (T != 0) {
00941     
00942     // *unbalance = (*T) * (*modUnbalance);
00943     myV->addMatrixVector(0.0, *T, *modUnbalance, 1.0);
00944     
00945   } else
00946     *myV = *modUnbalance;
00947 
00948 
00949   // Vel and Acc sensitivities only if they are being delivered
00950   if ((udot != 0) && (udotdot != 0)) {
00951     myVdot = new Vector(modNumDOF);
00952     myVdotdot = new Vector(modNumDOF);
00953     for (int i=0; i<modNumDOF; i++) {
00954       int loc = theID(i);
00955       if (loc >= 0)
00956         (*modUnbalance)(i) = (*udot)(loc);
00957       // DO THE SP STUFF
00958     }    
00959 
00960     if (T != 0) {
00961       
00962       // *unbalance = (*T) * (*modUnbalance);
00963       myVdot->addMatrixVector(0.0, *T, *modUnbalance, 1.0);
00964     
00965     } else
00966       *myVdot = *modUnbalance;
00967 
00968     for (int j=0; j<modNumDOF; j++) {
00969       int loc = theID(j);
00970       if (loc >= 0)
00971         (*modUnbalance)(j) = (*udotdot)(loc);
00972       // DO THE SP STUFF
00973     }    
00974 
00975     if (T != 0) {
00976       
00977       // *unbalance = (*T) * (*modUnbalance);
00978       myVdotdot->addMatrixVector(0.0, *T, *modUnbalance, 1.0);
00979     
00980     } else
00981       *myVdotdot = *modUnbalance;
00982 
00983   }
00984 
00985   myNode->saveSensitivity(myV, myVdot, myVdotdot, gradNum, numGrads);
00986   
00987   if (myV != 0) delete myV;
00988   if (myVdot != 0) delete myVdot;
00989   if (myVdotdot != 0) delete myVdotdot;
00990 
00991   return 0;
00992 }
00993 
00994 void  
00995 TransformationDOF_Group::addM_ForceSensitivity(const Vector &Udotdot, double fact)
00996 {
00997     // call base class method and return if no MP_Constraint
00998     if (theMP == 0 || modID == 0) {
00999         this->DOF_Group::addM_ForceSensitivity(Udotdot, fact);
01000         return;
01001     }
01002     
01003    for (int i=0; i<modNumDOF; i++) {
01004         int loc = (*modID)(i);
01005         if (loc >= 0)
01006             (*modUnbalance)(i) = Udotdot(loc);
01007         else    // DO THE SP STUFF
01008             (*modUnbalance)(i) = 0.0;       
01009     }    
01010 
01011     Vector unmod(Trans->noRows());
01012     //unmod = (*Trans) * (*modUnbalance);
01013     unmod.addMatrixVector(0.0, *Trans, *modUnbalance, 1.0);
01014     this->DOF_Group::addM_ForceSensitivity(unmod, fact);
01015 }
01016 
01017 void
01018 TransformationDOF_Group::addD_Force(const Vector &Udot, double fact)
01019 {
01020     // call base class method and return if no MP_Constraint
01021     if (theMP == 0 || modID == 0) {
01022         this->DOF_Group::addD_Force(Udot, fact);
01023         return;
01024     }
01025     
01026    for (int i=0; i<modNumDOF; i++) {
01027         int loc = (*modID)(i);
01028         if (loc >= 0)
01029             (*modUnbalance)(i) = Udot(loc);
01030         else    // DO THE SP STUFF
01031             (*modUnbalance)(i) = 0.0;       
01032     }    
01033 
01034     Vector unmod(Trans->noRows());
01035     //unmod = (*Trans) * (*modUnbalance);
01036     unmod.addMatrixVector(0.0, *Trans, *modUnbalance, 1.0);
01037     this->DOF_Group::addD_Force(unmod, fact);
01038 }
01039 
01040 void
01041 TransformationDOF_Group::addD_ForceSensitivity(const Vector &Udot, double fact)
01042 {
01043     // call base class method and return if no MP_Constraint
01044     if (theMP == 0 || modID == 0) {
01045         this->DOF_Group::addD_ForceSensitivity(Udot, fact);
01046         return;
01047     }
01048     
01049    for (int i=0; i<modNumDOF; i++) {
01050         int loc = (*modID)(i);
01051         if (loc >= 0)
01052             (*modUnbalance)(i) = Udot(loc);
01053         else    // DO THE SP STUFF
01054             (*modUnbalance)(i) = 0.0;       
01055     }    
01056 
01057     Vector unmod(Trans->noRows());
01058     //unmod = (*Trans) * (*modUnbalance);
01059     unmod.addMatrixVector(0.0, *Trans, *modUnbalance, 1.0);
01060     this->DOF_Group::addD_ForceSensitivity(unmod, fact);
01061 }
01062 
01063 // AddingSensitivity:END //////////////////////////////////////////

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