MP_Joint2D.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.6 $
00022 // $Date: 2004/09/01 04:01:27 $
00023 // $Source: /usr/local/cvs/OpenSees/SRC/element/joint/MP_Joint2D.cpp,v $
00024 
00025 // Written: Arash Altoontash, Gregory Deierlein
00026 // Created: 08/01
00027 // Revision: Arash
00028 
00029 // Purpose: This file contains the implementation of class MP_TimeVary.
00030 
00031 
00032 #include <MP_Joint2D.h>
00033 
00034 #include <stdlib.h>
00035 #include <math.h>
00036 
00037 #include <Matrix.h>
00038 #include <ID.h>
00039 #include <Channel.h>
00040 #include <FEM_ObjectBroker.h>
00041  
00042                                 // main degree of freedom for rotation
00043 
00044 // constructor for FEM_ObjectBroker
00045 MP_Joint2D::MP_Joint2D()
00046 :MP_Constraint( 0 , CNSTRNT_TAG_MP_Joint2D ),thisDomain(0),
00047  nodeRetained(0),nodeConstrained(0), MainDOF(0), AuxDOF(0), FixedEnd(0),
00048  constraint(0), constrDOF(0),retainDOF(0),dbTag1(0), dbTag2(0), dbTag3(0),
00049  RetainedNode(0), ConstrainedNode(0), LargeDisplacement(0), Length0(0.0)
00050 {
00051     
00052 }
00053 
00054 
00055 // general constructor for ModelBuilder
00056 MP_Joint2D::MP_Joint2D(Domain *theDomain, int tag, int nodeRetain, int nodeConstr,
00057                 int Maindof, int fixedend, int LrgDsp )
00058 :MP_Constraint( tag , CNSTRNT_TAG_MP_Joint2D ), thisDomain(theDomain),
00059  nodeRetained(nodeRetain), nodeConstrained(nodeConstr), MainDOF(Maindof), AuxDOF(0),
00060  FixedEnd(fixedend), constraint(0), constrDOF(0), retainDOF(0),
00061  dbTag1(0), dbTag2(0), dbTag3(0), RetainedNode(0), ConstrainedNode(0),
00062  LargeDisplacement( LrgDsp ), Length0(0.0)
00063 {
00064 
00065   if( thisDomain == NULL ) {
00066     opserr << "WARNING MP_Joint2D(): Specified domain does not exist";
00067     opserr << "Domain = 0\n";
00068     return;
00069   }
00070 
00071   this->setTag(tag);
00072 
00073         // get node pointers of constrainted and retained nodes
00074         ConstrainedNode = theDomain->getNode(nodeConstrained);
00075         if (ConstrainedNode == NULL)
00076         {
00077                 opserr << "MP_Joint2D::MP_Joint2D: nodeConstrained: ";
00078                 opserr << nodeConstrained << "does not exist in model\n";
00079                 exit(0);
00080         }
00081 
00082         RetainedNode = theDomain->getNode(nodeRetained);
00083         if (RetainedNode == NULL)
00084         {
00085                 opserr << "MP_Joint2D::MP_Joint2D: nodeRetained: ";
00086                 opserr << nodeRetained << "does not exist in model\n";
00087                 exit(0);
00088         }
00089 
00090         // check for proper degrees of freedom
00091         int RnumDOF = RetainedNode->getNumberDOF();
00092         int CnumDOF = ConstrainedNode->getNumberDOF();
00093     if (RnumDOF != 4 || CnumDOF != 3 ){
00094                 opserr << "MP_Joint2D::MP_Joint2D - mismatch in numDOF\n DOF not supported by this type of constraint";
00095                 return;
00096     }
00097 
00098         // check the main degree of freedom. Assign auxilary DOF 
00099         if ( MainDOF!= 2 && MainDOF!=3 ) {
00100                         opserr << "MP_Joint2D::MP_Joint2D - Wrong main degree of freedom" ;
00101                         return;
00102     }
00103         if ( MainDOF == 2 ) AuxDOF = 3;
00104         if ( MainDOF == 3 ) AuxDOF = 2;
00105         
00106         // check the fixed end flag
00107         if ( FixedEnd!= 0 && FixedEnd!=1 ) {
00108                         opserr << "MP_Joint2D::MP_Joint2D - Wrong fixed end flag";
00109                         return;
00110     }
00111         
00112 
00113         // check for proper dimensions of coordinate space
00114         const Vector &crdR = RetainedNode->getCrds();
00115     int dimR = crdR.Size();
00116         const Vector &crdC = ConstrainedNode->getCrds();
00117     int dimC = crdC.Size();
00118     
00119         if (dimR != 2 || dimC != 2 ){
00120                 opserr << "MP_Joint2D::MP_Joint2D - mismatch in dimnesion\n dimension not supported by this type of constraint";
00121                 return;
00122     }
00123 
00124 
00125         // calculate the initial length of the rigid link
00126         double deltaX = crdC(0) - crdR(0);
00127         double deltaY = crdC(1) - crdR(1);
00128 
00129         Length0 = sqrt( deltaX*deltaX + deltaY*deltaY );
00130     if ( Length0 <= 1.0e-12 ) {
00131                 opserr << "MP_Joint2D::MP_Joint2D - The constraint length is zero\n";
00132     }
00133    
00134         // allocate and set up the constranted and retained id's
00135         // allocate and set up the constraint matrix
00136         if ( FixedEnd == 0 )
00137         {
00138                 // the end is released
00139                 constrDOF = new ID(CnumDOF-1);
00140                 retainDOF = new ID(RnumDOF-1);
00141                 
00142                 (*constrDOF)(0) = 0;
00143                 (*constrDOF)(1) = 1;
00144 
00145                 (*retainDOF)(0) = 0;
00146                 (*retainDOF)(1) = 1;
00147                 (*retainDOF)(2) = MainDOF;
00148                 
00149                 constraint = new Matrix( CnumDOF-1 , RnumDOF-1 );
00150                 
00151                 (*constraint) (0,0) = 1.0 ;
00152                 (*constraint) (0,2) = -deltaY ;
00153                 (*constraint) (1,1) = 1.0 ;
00154                 (*constraint) (1,2) = deltaX ;
00155         } else
00156         {
00157                 // the end is fixed
00158                 constrDOF = new ID(CnumDOF);
00159                 retainDOF = new ID(RnumDOF);
00160                 
00161                 (*constrDOF)(0) = 0;
00162                 (*constrDOF)(1) = 1;
00163                 (*constrDOF)(2) = 2;
00164                 
00165                 (*retainDOF)(0) = 0;
00166                 (*retainDOF)(1) = 1;
00167                 (*retainDOF)(2) = 2;
00168                 (*retainDOF)(3) = 3;
00169                 
00170                 constraint = new Matrix( CnumDOF , RnumDOF );
00171                 
00172                 (*constraint) (0,0) = 1.0 ;
00173                 (*constraint) (0,MainDOF) = -deltaY ;
00174                 (*constraint) (1,1) = 1.0 ;
00175                 (*constraint) (1,MainDOF) = deltaX ;
00176                 (*constraint) (2,AuxDOF) = 1.0 ;
00177         }
00178  
00179         if (constrDOF == NULL || retainDOF == NULL ) { 
00180                 opserr << "MP_Joint2D::MP_Joint2D - ran out of memory \ncan not generate ID for nodes\n";
00181                 exit(-1);
00182         }
00183         
00184         if (constraint == NULL ) {
00185                 opserr << "MP_Joint2D::MP_Joint2D - ran out of memory \ncan not generate the constraint matrix";
00186                 exit(-1);
00187     }
00188 }
00189 
00190 
00191 
00192 MP_Joint2D::~MP_Joint2D()
00193 {
00194     // invoke the destructor on the matrix and the two ID objects
00195     if (constraint != NULL)
00196         delete constraint;
00197     if (constrDOF != NULL)
00198         delete constrDOF;
00199     if (retainDOF != NULL)
00200         delete retainDOF;    
00201 }
00202 
00203 
00204 int
00205 MP_Joint2D::getNodeRetained(void) const
00206 {
00207     // return id of retained node
00208     return nodeRetained;
00209 }
00210 
00211 int
00212 MP_Joint2D::getNodeConstrained(void) const
00213 {
00214     // return id of constrained node    
00215     return nodeConstrained;
00216 }
00217 
00218 
00219 const ID &
00220 MP_Joint2D::getConstrainedDOFs(void) const
00221 {
00222     if (constrDOF == NULL) {
00223         opserr << "MP_Joint2D::getConstrainedDOF - no ID was set, ";
00224         opserr << "was recvSelf() ever called? or subclass incorrect?\n";       
00225         exit(-1);
00226     }
00227 
00228     // return the ID corresponding to constrained DOF of Ccr
00229     return (*constrDOF);    
00230 }
00231 
00232 
00233 const ID &
00234 MP_Joint2D::getRetainedDOFs(void) const
00235 {
00236     if (retainDOF == NULL) {
00237         opserr << "MP_Joint2D::getRetainedDOFs - no ID was set\n ";
00238         opserr << "was recvSelf() ever called? or subclass incorrect?\n";               
00239         exit(-1);
00240     }
00241 
00242     // return the ID corresponding to retained DOF of Ccr
00243     return (*retainDOF);    
00244 }
00245 
00246 
00247 int 
00248 MP_Joint2D::applyConstraint(double timeStamp)
00249 {
00250     if ( LargeDisplacement != 0 )
00251         {
00252                 // calculate the constraint at this moment
00253 
00254                 // get the coordinates of the two nodes - check dimensions are the same FOR THE MOMENT
00255                 const Vector &crdR = RetainedNode->getCrds();
00256                 const Vector &crdC = ConstrainedNode->getCrds();
00257 
00258                 // get commited displacements of nodes to get updated coordinates
00259                 const Vector &dispR = RetainedNode->getDisp();
00260                 const Vector &dispC = ConstrainedNode->getDisp();
00261 
00262                 double deltaX = dispC(0) + crdC(0) - dispR(0) - crdR(0);
00263                 double deltaY = dispC(1) + crdC(1) - dispR(1) - crdR(1);
00264 
00265                 constraint->Zero();
00266                 
00267                 if ( FixedEnd == 0 )
00268                 {
00269                         // the end is released
00270                         (*constraint) (0,0) = 1.0 ;
00271                         (*constraint) (0,2) = -deltaY ;
00272                         (*constraint) (1,1) = 1.0 ;
00273                         (*constraint) (1,2) = deltaX ;
00274                 } else
00275                 {
00276                         // the end is fixed
00277                         (*constraint) (0,0) = 1.0 ;
00278                         (*constraint) (0,MainDOF) = -deltaY ;
00279                         (*constraint) (1,1) = 1.0 ;
00280                         (*constraint) (1,MainDOF) = deltaX ;
00281                         (*constraint) (2,AuxDOF) = 1.0 ;
00282                 }
00283         }
00284         return 0;
00285 }
00286 
00287 
00288 bool
00289 MP_Joint2D::isTimeVarying(void) const
00290 {
00291     if ( LargeDisplacement != 0 ) return true;
00292 
00293         return false;
00294 }
00295 
00296 
00297 int MP_Joint2D::sendSelf(int commitTag, Channel &theChannel)
00298 {
00299         Vector data(15);
00300     int dataTag = this->getDbTag();
00301 
00302     data(0) = this->getTag(); 
00303     data(1) = nodeRetained;
00304     data(2) = nodeConstrained;
00305     data(3) = MainDOF;
00306         data(4) = AuxDOF;
00307         data(5) = FixedEnd;
00308     
00309         if (constrDOF == 0) data(6) = 0; else data(6) = constrDOF->Size();    
00310         if (retainDOF == 0) data(7) = 0; else data(7) = retainDOF->Size();        
00311     if (constraint == 0) data(8) = 0; else data(8) = constraint->noRows();
00312         if (constraint == 0) data(9) = 0; else data(9) = constraint->noCols();   
00313     // need two database tags for ID objects
00314     if (constrDOF != 0 && dbTag1 == 0) dbTag1 = theChannel.getDbTag();
00315     if (retainDOF != 0 && dbTag2 == 0) dbTag2 = theChannel.getDbTag();
00316         if (constraint != 0 && dbTag3 == 0) dbTag3 = theChannel.getDbTag();
00317 
00318     data(10) = dbTag1;
00319     data(11) = dbTag2;
00320         data(12) = dbTag3;
00321     data(13) = LargeDisplacement;
00322     data(14) = Length0;
00323 
00324         // now send the data vector
00325     int result = theChannel.sendVector(dataTag, commitTag, data);
00326     if (result < 0) {
00327                 opserr << "WARNING MP_Joint2D::sendSelf - error sending ID data\n";
00328                 return result;  
00329     }    
00330     
00331         // send constrDOF
00332     if (constrDOF != 0 && constrDOF->Size() != 0) {
00333                 int result = theChannel.sendID(dbTag1, commitTag, *constrDOF);
00334                 if (result < 0) {
00335                         opserr << "WARNING MP_Joint2D::sendSelf ";
00336                         opserr << "- error sending constrained DOF data\n";
00337                         return result;
00338                 }
00339         }
00340 
00341         // send retainDOF
00342     if (retainDOF != 0 && retainDOF->Size() != 0) {
00343                 int result = theChannel.sendID(dbTag2, commitTag, *retainDOF);
00344                 if (result < 0) {
00345                         opserr << "WARNING MP_Joint2D::sendSelf ";
00346                         opserr << "- error sending retained DOF data\n";
00347                         return result;
00348                 }
00349     }
00350 
00351         // send constraint matrix 
00352     if (constraint != 0 && constraint->noRows() != 0) {
00353 
00354 
00355         int result = theChannel.sendMatrix(dbTag3, commitTag, *constraint);
00356         if (result < 0) {
00357             opserr << "WARNING MP_Joint2D::sendSelf ";
00358             opserr << "- error sending constraint Matrix data\n"; 
00359             return result;  
00360         }
00361     }
00362 
00363     return 0;
00364 }
00365 
00366 
00367 int MP_Joint2D::recvSelf(int commitTag, Channel &theChannel, 
00368                          FEM_ObjectBroker &theBroker)
00369 {
00370     int dataTag = this->getDbTag();
00371     Vector data(15);
00372     int result = theChannel.recvVector(dataTag, commitTag, data);
00373     if (result < 0) {
00374         opserr << "WARNING MP_Joint2D::recvSelf - error receiving ID data\n";
00375         return result;  
00376     }    
00377 
00378     this->setTag( (int) data(0));
00379     nodeRetained = (int) data(1);
00380     nodeConstrained = (int) data(2);
00381     MainDOF = (int) data(3);
00382         AuxDOF = (int) data(4);
00383         FixedEnd = (int) data(5);
00384 
00385         int constrDOFsize = (int) data(6);
00386         int retainDOFsize = (int) data(7);
00387     int numRows = (int) data(8);
00388         int numCols = (int) data(9); 
00389         
00390         dbTag1 = (int) data(10);
00391     dbTag2 = (int) data(11);
00392     dbTag3 = (int) data(12);
00393         LargeDisplacement = (int) data(13);
00394     Length0 = data(14);
00395 
00396 
00397     // receive constrDOF ID
00398     if (constrDOFsize != 0) {
00399         constrDOF = new ID(constrDOFsize);
00400         int result = theChannel.recvID(dbTag1, commitTag, *constrDOF);
00401         if (result < 0) {
00402             opserr << "WARNING MP_Joint2D::recvSelf ";
00403             opserr << "- error receiving constrained data\n"; 
00404             return result;  
00405         }       
00406     }
00407     
00408     // receive retainDOF ID
00409     if (retainDOFsize != 0) {
00410         retainDOF = new ID(retainDOFsize);
00411         int result = theChannel.recvID(dbTag2, commitTag, *retainDOF);
00412         if (result < 0) {
00413             opserr << "WARNING MP_Joint2D::recvSelf ";
00414             opserr << "- error receiving retained data\n"; 
00415             return result;  
00416         }       
00417     }    
00418     
00419     // receive the constraint matrix
00420         if (numRows != 0 && numCols != 0) {
00421                 constraint = new Matrix(numRows,numCols);
00422 
00423                 int result = theChannel.recvMatrix(dbTag3, commitTag, *constraint);
00424                 
00425                 if (result < 0) {
00426                         opserr << "WARNING MP_Joint2D::recvSelf ";
00427                         opserr << "- error receiving Matrix data\n";
00428                         return result;
00429                 }
00430         }
00431 
00432     return 0;
00433 }
00434 
00435 
00436 const Matrix &MP_Joint2D::getConstraint(void)
00437 {
00438     if (constraint == 0) {
00439         opserr << "MP_Joint2D::getConstraint - no Matrix was set\n";
00440         exit(-1);
00441     }    
00442 
00443         // Length correction
00444         // to correct the trial displacement
00445     if ( LargeDisplacement == 2 )
00446         {
00447                 // get the coordinates of the two nodes - check dimensions are the same FOR THE MOMENT
00448                 const Vector &crdR = RetainedNode->getCrds();
00449                 const Vector &crdC = ConstrainedNode->getCrds();
00450 
00451                 // get commited displacements of nodes to get updated coordinates
00452                 const Vector &dispR = RetainedNode->getTrialDisp();
00453                 const Vector &dispC = ConstrainedNode->getTrialDisp();
00454 
00455                 double deltaX = dispC(0) + crdC(0) - dispR(0) - crdR(0);
00456                 double deltaY = dispC(1) + crdC(1) - dispR(1) - crdR(1);
00457 
00458 
00459                 Vector Direction(2);
00460                 Direction(0) = deltaX;
00461                 Direction(1) = deltaY;
00462                 double NewLength = Direction.Norm();
00463                 if ( NewLength < 1e-12 ) opserr << "MP_Joint2D::applyConstraint : length of rigid link is too small or zero"; 
00464                 Direction = Direction * (Length0/NewLength);            // correct the length
00465                 // find new displacements of the constrainted node
00466         
00467                 Vector NewLocation(3);
00468                 NewLocation(0) = Direction(0) + dispR(0) + crdR(0) - crdC(0);
00469                 NewLocation(1) = Direction(1) + dispR(1) + crdR(1) - crdC(1);
00470                 NewLocation(2) = dispC(2);
00471                 int dummy = ConstrainedNode->setTrialDisp( NewLocation );
00472         }
00473         // end of length correction procedure
00474 
00475     // return the constraint matrix Ccr
00476     return (*constraint);
00477 }
00478     
00479 void MP_Joint2D::Print(OPS_Stream &s, int flag )
00480 {
00481     s << "MP_Joint2D: " << this->getTag() << "\n";
00482     s << "\tConstrained Node: " << nodeConstrained;
00483     s << " Retained Node: " << nodeRetained ;
00484         s << " Fixed end: " << FixedEnd << " Large Disp: " << LargeDisplacement;
00485     if (constrDOF != 0)
00486         s << " constrained dof: " << *constrDOF;    
00487     if (retainDOF != 0)
00488         s << " retained dof: " << *retainDOF;        
00489     if (constraint != 0)
00490         s << " constraint matrix: " << *constraint << "\n";
00491 
00492 }
00493 
00494 
00495 void
00496 MP_Joint2D::setDomain(Domain *theDomain)
00497 {
00498         this->DomainComponent::setDomain(theDomain);
00499         thisDomain = theDomain;
00500 
00501     RetainedNode = thisDomain->getNode(nodeRetained);
00502     ConstrainedNode = thisDomain->getNode(nodeConstrained);
00503 }
00504 
00505 

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