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.10 $
00022 // $Date: 2006/09/05 21:13:27 $
00023 // $Source: /usr/local/cvs/OpenSees/SRC/element/joint/Joint2D.cpp,v $
00024 
00025 // Written: Arash & GGD
00026 // Created: 03/02
00027 // Revision: Arash
00028 
00029 // Joint2D.cpp: implementation of the Joint2D class.
00030 //
00032 
00033 #include <stdio.h>
00034 #include <Channel.h>
00035 #include <FEM_ObjectBroker.h>
00036 #include <Renderer.h>
00037 #include <Information.h>
00038 #include <Parameter.h>
00039 #include <math.h>
00040 #include <stdlib.h>
00041 #include <string.h>
00042 #include <MP_Constraint.h>
00043 #include <MP_Joint2D.h>
00044 #include <ElementResponse.h>
00045 #include <UniaxialMaterial.h>
00046 #include <Joint2D.h>
00047 #include <DamageModel.h>
00048 
00049 
00050 Matrix Joint2D::K(16,16);
00051 Vector Joint2D::V(16);
00052 
00054 // Construction/Destruction
00056 
00057 
00058 Joint2D::Joint2D()
00059   :Element(0, ELE_TAG_Joint2D ), 
00060   ExternalNodes(5), InternalConstraints(4), 
00061   TheDomain(0), numDof(0), nodeDbTag(0), dofDbTag(0)
00062 {
00063         for ( int i=0 ; i<5 ; i++ )
00064         {
00065                 theSprings[i] = NULL;;
00066                 fixedEnd[i] = 1;
00067                 theNodes[i] = NULL;
00068         }
00069 }
00070 
00071 
00072 Joint2D::Joint2D(int tag, int nd1, int nd2, int nd3, int nd4, int IntNodeTag,
00073                              UniaxialMaterial &spring1, UniaxialMaterial &spring2,
00074                              UniaxialMaterial &spring3, UniaxialMaterial &spring4,
00075                              UniaxialMaterial &springC, Domain *theDomain, int LrgDisp)
00076   :Element(tag, ELE_TAG_Joint2D ), 
00077   ExternalNodes(5), InternalConstraints(4), 
00078   TheDomain(0), numDof(0), nodeDbTag(0), dofDbTag(0),theLoadSens(0)
00079 {
00080   int i;
00081   numDof  = 16;
00082 
00083   K.Zero();
00084   V.Zero();
00085 
00086   TheDomain = theDomain;
00087   if( TheDomain==NULL ) {
00088     opserr << "WARNING Joint2D(): Specified domain does not exist , Domain = 0\n";
00089     return;
00090   }
00091 
00092   // Save external node id's
00093   ExternalNodes(0) = nd1;
00094   ExternalNodes(1) = nd2;
00095   ExternalNodes(2) = nd3;
00096   ExternalNodes(3) = nd4;
00097   ExternalNodes(4) = IntNodeTag;
00098   
00099 
00100   // get  the external nodes
00101   for ( i=0 ; i<4 ; i++)
00102   {
00103     theNodes[i] = NULL;
00104     theNodes[i] = TheDomain->getNode( ExternalNodes(i) );
00105     if (theNodes[i] == NULL) {
00106       opserr << "WARNING Joint2D::setDomain(): Nd" <<(i+1) <<": ";
00107       opserr << ExternalNodes(i) << "does not exist in model for element \n" << *this;
00108       return;
00109     }
00110   }
00111   
00112   // check for a two dimensional domain, since this element supports only two dimensions 
00113   const Vector &end1Crd = theNodes[0]->getCrds();
00114   const Vector &end2Crd = theNodes[1]->getCrds();       
00115   const Vector &end3Crd = theNodes[2]->getCrds();
00116   const Vector &end4Crd = theNodes[3]->getCrds();
00117   
00118   int dimNd1 = end1Crd.Size();
00119   int dimNd2 = end2Crd.Size();
00120   int dimNd3 = end3Crd.Size();
00121   int dimNd4 = end4Crd.Size();
00122 
00123   if (dimNd1 != 2 || dimNd2 != 2 || dimNd3 != 2 || dimNd4 != 2 ) {
00124     opserr << "WARNING Joint2D::setDomain(): has incorrect space dimension \n";
00125     opserr << "                                    space dimension not supported by Joint2D";
00126     return;
00127   }
00128         
00129   // now verify the number of dof at node ends
00130   int dofNd1 = theNodes[0]->getNumberDOF();
00131   int dofNd2 = theNodes[1]->getNumberDOF();     
00132   int dofNd3 = theNodes[2]->getNumberDOF();
00133   int dofNd4 = theNodes[3]->getNumberDOF();
00134 
00135   if (dofNd1 != 3 || dofNd2 != 3 || dofNd3 != 3 || dofNd4 != 3 ) {
00136     opserr << "WARNING Joint2D::Joint2D: has incorrect degrees of freedom \n";
00137     opserr << "                                    DOF not supported by Joint2D";
00138     return;
00139   }
00140   
00141   // check the joint size. The joint size must be non-zero
00142   Vector Center1(end1Crd);
00143   Vector Center2(end2Crd);
00144   Center1 = Center1 - end3Crd;
00145   Center2 = Center2 - end4Crd;
00146         
00147   double L1 = Center1.Norm();
00148   double L2 = Center2.Norm();
00149   
00150   if( Center1.Norm()<1e-12  || Center2.Norm()<1e-12 ) {
00151     opserr << "WARNING Joint2D::(): zero length\n";
00152     return;     
00153   }
00154         
00155   // check if nodes are not located on each other and they can construct
00156   // a parallelogram
00157   Center1 = end1Crd + end3Crd;
00158   Center2 = end2Crd + end4Crd;
00159   
00160   Center1 = 0.5 * Center1;
00161   Center2 = 0.5 * Center2;
00162   
00163   Vector Center3(Center2);
00164   Center3 = Center3 - Center1;
00165 
00166   if ( Center3.Norm() > 1e-6 ) {
00167     opserr << "WARNING Joint2D::(): can not construct a paralelogram over external nodes\n";
00168     return;     
00169   }
00170         
00171   // Generate internal node and add it up to domain
00172   theNodes[4]  = new Node ( IntNodeTag , 4, Center1(0) , Center1(1) );
00173   if ( theNodes[4] == NULL ) {
00174     opserr << "Joint2D::Joint2D - Unable to generate new nodes , out of memory\n" ;
00175   } else {
00176     if( TheDomain->addNode( theNodes[4] ) == false )            // add intenal nodes to domain
00177       opserr << "Joint2D::Joint2D - unable to add internal nodeto domain\n";
00178   }
00179   
00180   // make copy of the uniaxial materials for the element
00181   
00182   if ( &spring1 == NULL ) { fixedEnd[0] = 1;  theSprings[0] = NULL; } else { fixedEnd[0] = 0; theSprings[0] = spring1.getCopy(); }
00183   if ( &spring2 == NULL ) { fixedEnd[1] = 1;  theSprings[1] = NULL; } else { fixedEnd[1] = 0; theSprings[1] = spring2.getCopy(); }  
00184   if ( &spring3 == NULL ) { fixedEnd[2] = 1;  theSprings[2] = NULL; } else { fixedEnd[2] = 0; theSprings[2] = spring3.getCopy(); }
00185   if ( &spring4 == NULL ) { fixedEnd[3] = 1;  theSprings[3] = NULL; } else { fixedEnd[3] = 0; theSprings[3] = spring4.getCopy(); }
00186   if ( &springC == NULL ) { opserr << "ERROR Joint2D::Joint2D(): The central node does not exist "; exit(-1); } else { fixedEnd[4] = 0; theSprings[4] = springC.getCopy(); }
00187   
00188   
00189   for ( i=0 ; i<5 ; i++ )
00190     {
00191       if ( fixedEnd[i] == 0  && theSprings[i] == NULL ) {
00192         opserr << "ERROR Joint2D::Joint2D(): Can not make copy of uniaxial materials, out of memory ";
00193         exit(-1);
00194       }
00195     }
00196   
00197   // Generate and add constraints to domain
00198   
00199   // get the constraint numbers
00200   int startMPtag = theDomain->getNumMPs();
00201   for ( i=0 ; i<4 ; i++ ) InternalConstraints(i) = startMPtag + i ;
00202   
00203   // create MP_Joint constraint node 1
00204   if ( addMP_Joint( TheDomain, InternalConstraints(0), ExternalNodes(4), ExternalNodes(0), 2, fixedEnd[0], LrgDisp ) != 0) {
00205     opserr << "WARNING Joint2D::Joint2D(): can not generate ForJoint MP at node 1\n";
00206     return;
00207   }
00208   
00209   // create MP_Joint constraint node 2
00210   if ( addMP_Joint( TheDomain, InternalConstraints(1), ExternalNodes(4), ExternalNodes(1), 3, fixedEnd[1], LrgDisp ) != 0) {
00211     opserr << "WARNING Joint2D::Joint2D(): can not generate ForJoint MP at node 2\n";
00212                 return;
00213   }
00214   
00215   // create MP_Joint constraint node 3
00216   if ( addMP_Joint( TheDomain, InternalConstraints(2), ExternalNodes(4), ExternalNodes(2), 2, fixedEnd[2], LrgDisp ) != 0) {
00217     opserr << "WARNING Joint2D::Joint2D(): can not generate ForJoint MP at node 3\n";
00218     return;
00219   }
00220   
00221   // create MP_Joint constraint node 4
00222   if ( addMP_Joint( TheDomain, InternalConstraints(3), ExternalNodes(4), ExternalNodes(3), 3, fixedEnd[3], LrgDisp ) != 0) {
00223     opserr << "WARNING Joint2D::Joint2D(): can not generate ForJoint MP at node 4\n";
00224     return;
00225   }
00226 
00227   // Zero the damage models
00228   for ( i = 0 ; i < 5 ; i++ ) theDamages[i] = NULL;
00229 }
00230 
00231 
00232 Joint2D::Joint2D(int tag, int nd1, int nd2, int nd3, int nd4, int IntNodeTag,
00233                              UniaxialMaterial &spring1, UniaxialMaterial &spring2,
00234                              UniaxialMaterial &spring3, UniaxialMaterial &spring4,
00235                              UniaxialMaterial &springC, Domain *theDomain, int LrgDisp,
00236                                  DamageModel &dmg1, DamageModel &dmg2, DamageModel &dmg3,
00237                                  DamageModel &dmg4, DamageModel &dmgC)
00238   :Element(tag, ELE_TAG_Joint2D ), 
00239   ExternalNodes(5), InternalConstraints(4), 
00240   TheDomain(0), numDof(0), nodeDbTag(0), dofDbTag(0),theLoadSens(0)
00241 {
00242   int i;
00243   numDof  = 16;
00244 
00245   K.Zero();
00246   V.Zero();
00247 
00248   TheDomain = theDomain;
00249   if( TheDomain==NULL ) {
00250     opserr << "WARNING Joint2D(): Specified domain does not exist , Domain = 0\n";
00251     return;
00252   }
00253 
00254   // Save external node id's
00255   ExternalNodes(0) = nd1;
00256   ExternalNodes(1) = nd2;
00257   ExternalNodes(2) = nd3;
00258   ExternalNodes(3) = nd4;
00259   ExternalNodes(4) = IntNodeTag;
00260   
00261 
00262   // get  the external nodes
00263   for ( i=0 ; i<4 ; i++)
00264   {
00265     theNodes[i] = NULL;
00266     theNodes[i] = TheDomain->getNode( ExternalNodes(i) );
00267     if (theNodes[i] == NULL) {
00268       opserr << "WARNING Joint2D::setDomain(): Nd" <<(i+1) <<": ";
00269       opserr << ExternalNodes(i) << "does not exist in model for element \n" << *this;
00270       return;
00271     }
00272   }
00273   
00274   // check for a two dimensional domain, since this element supports only two dimensions 
00275   const Vector &end1Crd = theNodes[0]->getCrds();
00276   const Vector &end2Crd = theNodes[1]->getCrds();       
00277   const Vector &end3Crd = theNodes[2]->getCrds();
00278   const Vector &end4Crd = theNodes[3]->getCrds();
00279   
00280   int dimNd1 = end1Crd.Size();
00281   int dimNd2 = end2Crd.Size();
00282   int dimNd3 = end3Crd.Size();
00283   int dimNd4 = end4Crd.Size();
00284 
00285   if (dimNd1 != 2 || dimNd2 != 2 || dimNd3 != 2 || dimNd4 != 2 ) {
00286     opserr << "WARNING Joint2D::setDomain(): has incorrect space dimension \n";
00287     opserr << "                                    space dimension not supported by Joint2D";
00288     return;
00289   }
00290         
00291   // now verify the number of dof at node ends
00292   int dofNd1 = theNodes[0]->getNumberDOF();
00293   int dofNd2 = theNodes[1]->getNumberDOF();     
00294   int dofNd3 = theNodes[2]->getNumberDOF();
00295   int dofNd4 = theNodes[3]->getNumberDOF();
00296 
00297   if (dofNd1 != 3 || dofNd2 != 3 || dofNd3 != 3 || dofNd4 != 3 ) {
00298     opserr << "WARNING Joint2D::Joint2D: has incorrect degrees of freedom \n";
00299     opserr << "                                    DOF not supported by Joint2D";
00300     return;
00301   }
00302   
00303   // check the joint size. The joint size must be non-zero
00304   Vector Center1(end1Crd);
00305   Vector Center2(end2Crd);
00306   Center1 = Center1 - end3Crd;
00307   Center2 = Center2 - end4Crd;
00308         
00309   double L1 = Center1.Norm();
00310   double L2 = Center2.Norm();
00311   
00312   if( Center1.Norm()<1e-12  || Center2.Norm()<1e-12 ) {
00313     opserr << "WARNING Joint2D::(): zero length\n";
00314     return;     
00315   }
00316         
00317   // check if nodes are not located on each other and they can construct
00318   // a parallelogram
00319   Center1 = end1Crd + end3Crd;
00320   Center2 = end2Crd + end4Crd;
00321   
00322   Center1 = 0.5 * Center1;
00323   Center2 = 0.5 * Center2;
00324   
00325   Vector Center3(Center2);
00326   Center3 = Center3 - Center1;
00327 
00328   if ( Center3.Norm() > 1e-6 ) {
00329     opserr << "WARNING Joint2D::(): can not construct a paralelogram over external nodes\n";
00330     return;     
00331   }
00332         
00333   // Generate internal node and add it up to domain
00334   theNodes[4]  = new Node ( IntNodeTag , 4, Center1(0) , Center1(1) );
00335   if ( theNodes[4] == NULL ) {
00336     opserr << "Joint2D::Joint2D - Unable to generate new nodes , out of memory\n" ;
00337   } else {
00338     if( TheDomain->addNode( theNodes[4] ) == false )            // add intenal nodes to domain
00339       opserr << "Joint2D::Joint2D - unable to add internal nodeto domain\n";
00340   }
00341   
00342   // make copy of the uniaxial materials for the element
00343   
00344   if ( &spring1 == NULL )       { fixedEnd[0] = 1;  theSprings[0] = NULL; }     else { fixedEnd[0] = 0; theSprings[0] = spring1.getCopy(); }
00345   if ( &spring2 == NULL ) { fixedEnd[1] = 1;  theSprings[1] = NULL; } else { fixedEnd[1] = 0; theSprings[1] = spring2.getCopy(); }  
00346   if ( &spring3 == NULL ) { fixedEnd[2] = 1;  theSprings[2] = NULL; } else { fixedEnd[2] = 0; theSprings[2] = spring3.getCopy(); }
00347   if ( &spring4 == NULL ) { fixedEnd[3] = 1;  theSprings[3] = NULL; } else { fixedEnd[3] = 0; theSprings[3] = spring4.getCopy(); }
00348   if ( &springC == NULL ) { opserr << "ERROR Joint2D::Joint2D(): The central node does not exist "; exit(-1); } else { fixedEnd[4] = 0; theSprings[4] = springC.getCopy(); }
00349   
00350   
00351   for ( i=0 ; i<5 ; i++ )
00352     {
00353       if ( fixedEnd[i] == 0  && theSprings[i] == NULL ) {
00354         opserr << "ERROR Joint2D::Joint2D(): Can not make copy of uniaxial materials, out of memory ";
00355         exit(-1);
00356       }
00357     }
00358   
00359   // Generate and add constraints to domain
00360   
00361   // get the constraint numbers
00362   int startMPtag = theDomain->getNumMPs();
00363   for ( i=0 ; i<4 ; i++ ) InternalConstraints(i) = startMPtag + i ;
00364   
00365   // create MP_Joint constraint node 1
00366   if ( addMP_Joint( TheDomain, InternalConstraints(0), ExternalNodes(4), ExternalNodes(0), 2, fixedEnd[0], LrgDisp ) != 0) {
00367     opserr << "WARNING Joint2D::Joint2D(): can not generate ForJoint MP at node 1\n";
00368     return;
00369   }
00370   
00371   // create MP_Joint constraint node 2
00372   if ( addMP_Joint( TheDomain, InternalConstraints(1), ExternalNodes(4), ExternalNodes(1), 3, fixedEnd[1], LrgDisp ) != 0) {
00373     opserr << "WARNING Joint2D::Joint2D(): can not generate ForJoint MP at node 2\n";
00374                 return;
00375   }
00376   
00377   // create MP_Joint constraint node 3
00378   if ( addMP_Joint( TheDomain, InternalConstraints(2), ExternalNodes(4), ExternalNodes(2), 2, fixedEnd[2], LrgDisp ) != 0) {
00379     opserr << "WARNING Joint2D::Joint2D(): can not generate ForJoint MP at node 3\n";
00380     return;
00381   }
00382   
00383   // create MP_Joint constraint node 4
00384   if ( addMP_Joint( TheDomain, InternalConstraints(3), ExternalNodes(4), ExternalNodes(3), 3, fixedEnd[3], LrgDisp ) != 0) {
00385     opserr << "WARNING Joint2D::Joint2D(): can not generate ForJoint MP at node 4\n";
00386     return;
00387   }
00388         // Handle the damage models
00389         if ( &dmg1 == NULL ) { theDamages[0] = NULL; } else { theDamages[0] = dmg1.getCopy(); }
00390         if ( &dmg2 == NULL ) { theDamages[1] = NULL; } else { theDamages[1] = dmg2.getCopy(); }
00391         if ( &dmg3 == NULL ) { theDamages[2] = NULL; } else { theDamages[2] = dmg3.getCopy(); }
00392         if ( &dmg4 == NULL ) { theDamages[3] = NULL; } else { theDamages[3] = dmg4.getCopy(); }
00393         if ( &dmgC == NULL ) { theDamages[4] = NULL; } else { theDamages[4] = dmgC.getCopy(); }
00394 
00395         for ( i = 0 ; i < 5 ; i ++ ) if ( theDamages[i] != NULL ) theDamages[i]->revertToStart();
00396                                 
00397 }
00398 
00399 
00400 Joint2D::~Joint2D()
00401 {
00402 
00403         if ( TheDomain != NULL)
00404         {
00405                 MP_Constraint *Temp_MP;
00406                 for ( int i=0 ; i < 4 ; i++ )
00407                 {
00408                         Temp_MP = TheDomain->getMP_Constraint( InternalConstraints(i) );
00409                         
00410                         if ( Temp_MP != NULL )
00411                         {
00412                                 TheDomain->removeMP_Constraint( InternalConstraints(i) );
00413                                 delete Temp_MP;
00414                         }
00415                 }
00416                 if ( theNodes[4] != NULL )
00417                 {
00418                         int intnodetag = theNodes[4]->getTag();
00419                         TheDomain->removeNode( intnodetag );
00420                         delete theNodes[4];
00421                 }
00422         }
00423 
00424         for (int i=0 ; i<5 ; i++) {
00425                 if ( theSprings[i] != NULL ) delete theSprings[i];
00426                 if ( theDamages[i] != NULL ) delete theDamages[i];
00427         }
00428 }
00429 
00430 
00431 void Joint2D::setDomain(Domain *theDomain)
00432 {
00433         //Ckeck domain not null - invoked when object removed from a domain
00434         if (theDomain == 0) {
00435                 for(int i=0 ; i<4 ; i++) theNodes[i] = NULL;
00436         } else {
00437                 
00438                 TheDomain = theDomain;
00439                 this->DomainComponent::setDomain(theDomain);
00440                 
00441                 for (int i=0 ; i<5 ; i++)
00442                         if ( theNodes[i] ==0 )  theNodes[i] = TheDomain->getNode( ExternalNodes(i) );
00443         }
00444         
00445 }//setDomain
00446 
00447 
00448 int Joint2D::addMP_Joint(Domain *theDomain, int mpNum, 
00449                                   int RnodeID, int CnodeID, 
00450                                   int MainDOF, int FixedEnd, int LrgDispFlag )
00451 {
00452         MP_Constraint *Temp_MP;
00453 
00454         // create MP_ForJoint constraint
00455         Temp_MP = new MP_Joint2D( theDomain, mpNum, RnodeID, CnodeID, MainDOF, FixedEnd, LrgDispFlag );
00456   
00457         if (Temp_MP == NULL)
00458         {
00459                 opserr << "Joint2D::addMP_Joint - WARNING ran out of memory for ForJoint MP_Constraint ";
00460                 return -1;
00461         }
00462         // Add the multi-point constraint to the domain
00463         if (theDomain->addMP_Constraint (Temp_MP) == false)
00464         {
00465                 opserr << "Joint2D::addMP_Joint - WARNING could not add equalDOF MP_Constraint to domain ";
00466                 delete Temp_MP;
00467                 return -2;
00468         }
00469         return 0;
00470 }
00471 
00473 // Public methods called, taken care of for 2D element subclasses
00475 
00476 int Joint2D::update(void)
00477 {
00478         const Vector &disp1 = theNodes[0]->getTrialDisp();
00479         const Vector &disp2 = theNodes[1]->getTrialDisp();
00480         const Vector &disp3 = theNodes[2]->getTrialDisp();
00481         const Vector &disp4 = theNodes[3]->getTrialDisp();
00482         const Vector &dispC = theNodes[4]->getTrialDisp();
00483         double Delta[5];
00484         Delta[0] = disp1(2) - dispC(3);
00485         Delta[1] = disp2(2) - dispC(2);
00486         Delta[2] = disp3(2) - dispC(3);
00487         Delta[3] = disp4(2) - dispC(2);
00488         Delta[4] = dispC(3) - dispC(2);
00489         int result = 0;
00490 
00491         for ( int i=0 ; i<5 ; i++ )
00492         {
00493                 if ( theSprings[i] != NULL ) result = theSprings[i]->setTrialStrain(Delta[i]);
00494                 if ( result != 0 ) break;
00495         }
00496 
00497         return result;
00498 }
00499 
00500 int Joint2D::commitState()
00501 {
00502         int result = 0;
00503 
00504 
00505         // setting the trial state for the damage models
00506 
00507         Vector InforForDamage(3);
00508 
00509 
00510         for ( int i=0 ; i<5 ; i++ )
00511         {
00512                 if ( theSprings[i] != NULL ) result = theSprings[i]->commitState();
00513                 if ( result != 0 ) break;
00514 
00515                 if ( theSprings[i] != NULL && theDamages[i] != NULL ) {
00516                         InforForDamage(0) = theSprings[i]->getStrain();
00517                         InforForDamage(1) = theSprings[i]->getStress();
00518                         InforForDamage(2) = theSprings[i]->getInitialTangent();
00519                                 
00520                         theDamages[i]->setTrial(InforForDamage);
00521                         result = theDamages[i]->commitState();
00522                         if ( result != 0 ) break;
00523                 }
00524 
00525         }
00526         
00527         return result;
00528 }
00529 
00530 int Joint2D::revertToLastCommit()
00531 {
00532         int result = 0;
00533 
00534         for ( int i=0 ; i<5 ; i++ )
00535         {
00536                 if ( theSprings[i] != NULL ) result = theSprings[i]->revertToLastCommit();
00537                 if ( result != 0 ) break;
00538                 if ( theDamages[i] != NULL ) result = theDamages[i]->revertToLastCommit();
00539                 if ( result != 0 ) break;
00540         }
00541         
00542         return result;
00543 }
00544 
00545 int Joint2D::revertToStart(void)
00546 {
00547         int result = 0;
00548 
00549         for ( int i=0 ; i<5 ; i++ )
00550         {
00551                 if ( theSprings[i] != NULL ) result = theSprings[i]->revertToStart();
00552                 if ( result != 0 ) break;
00553                 if ( theDamages[i] != NULL ) result = theDamages[i]->revertToStart();
00554                 if ( result != 0 ) break;
00555         }
00556         
00557         return result;
00558 }
00559 
00560 
00561 int Joint2D::getNumExternalNodes(void) const
00562 {
00563         return 5;
00564 }
00565 
00566 const ID &Joint2D::getExternalNodes(void)
00567 {
00568         return ExternalNodes;
00569 }
00570 
00571 Node **Joint2D::getNodePtrs(void)
00572 {
00573         return theNodes;
00574 }
00575 
00576 int Joint2D::getNumDOF(void)
00577 {
00578   return numDof;
00579 }
00580 
00581 const Matrix &Joint2D::getTangentStiff(void)
00582 {
00583         double Ktangent[5] ;
00584         for ( int i=0 ; i<5 ; i++ ) 
00585         {
00586                 Ktangent[i] = 0;
00587                 if ( theSprings[i] != NULL ) Ktangent[i] = theSprings[i]->getTangent();
00588         }
00589 
00590         K.Zero();
00591 
00592         K(2,2)  =  Ktangent[0];
00593         K(2,15) = -Ktangent[0];
00594         K(5,5)  =  Ktangent[1];
00595         K(5,14) = -Ktangent[1];
00596         K(8,8)  =  Ktangent[2];
00597         K(8,15) = -Ktangent[2];
00598         K(11,11)=  Ktangent[3];
00599         K(11,14)= -Ktangent[3];
00600         K(14,5) = -Ktangent[1];
00601         K(14,11)= -Ktangent[3];
00602         K(14,14)=  Ktangent[1] + Ktangent[3] + Ktangent[4];
00603         K(14,15)= -Ktangent[4];
00604         K(15,2) = -Ktangent[0];
00605         K(15,8) = -Ktangent[2];
00606         K(15,14)= -Ktangent[4];
00607         K(15,15)=  Ktangent[0] + Ktangent[2] + Ktangent[4];
00608 
00609         return K;
00610 }
00611 
00612 
00613 const Matrix &Joint2D::getInitialStiff(void)
00614 {
00615         double Kintial[5] ;
00616         for ( int i=0 ; i<5 ; i++ ) 
00617         {
00618                 Kintial[i] = 0;
00619                 if ( theSprings[i] != NULL ) Kintial[i] = theSprings[i]->getTangent();
00620         }
00621 
00622         K.Zero();
00623 
00624         K(2,2)  =  Kintial[0];
00625         K(2,15) = -Kintial[0];
00626         K(5,5)  =  Kintial[1];
00627         K(5,14) = -Kintial[1];
00628         K(8,8)  =  Kintial[2];
00629         K(8,15) = -Kintial[2];
00630         K(11,11)=  Kintial[3];
00631         K(11,14)= -Kintial[3];
00632         K(14,5) = -Kintial[1];
00633         K(14,11)= -Kintial[3];
00634         K(14,14)=  Kintial[1] + Kintial[3] + Kintial[4];
00635         K(14,15)= -Kintial[4];
00636         K(15,2) = -Kintial[0];
00637         K(15,8) = -Kintial[2];
00638         K(15,14)= -Kintial[4];
00639         K(15,15)=  Kintial[0] + Kintial[2] + Kintial[4];
00640 
00641         return K;
00642 }
00643 
00644 
00645 const Matrix &Joint2D::getDamp(void)
00646 {       
00647         K.Zero();
00648         return K;
00649 }
00650 
00651 const Matrix &Joint2D::getMass(void)
00652 {
00653         K.Zero();
00654         return K;
00655 }
00656 
00657 void Joint2D::Print(OPS_Stream &s, int flag )
00658 {
00659   s << "\nElement: " << getTag() << " type: Joint2D iNode: "
00660     << ExternalNodes(0) << " jNode: " << ExternalNodes(1) << "\n"
00661     << " kNode: " << ExternalNodes(2) << " lNode: " << ExternalNodes(3) << "\n"
00662         << " Internal node: " << ExternalNodes(4) << "\n";
00663 }
00664 
00666 // methods for applying and returning loads
00668 
00669 void Joint2D::zeroLoad(void)
00670 {
00671 
00672 }
00673 
00674 int Joint2D::addLoad(ElementalLoad *theLoad, double loadFactor)
00675 {
00676   return 0;
00677 }
00678 
00679 int Joint2D::addInertiaLoadToUnbalance(const Vector &accel)
00680 {
00681     return 0;
00682 }
00683 
00684 
00685 
00686 const Vector &Joint2D::getResistingForce()
00687 {
00688         double Force[5] ;
00689         for ( int i=0 ; i<5 ; i++ ) 
00690         {
00691                 Force[i] = 0;
00692                 if ( theSprings[i] != NULL ) Force[i] = theSprings[i]->getStress();
00693         }
00694 
00695         V.Zero();
00696 
00697         V(2) = Force[0];
00698         V(5) = Force[1];
00699         V(8) = Force[2];
00700         V(11)= Force[3];
00701         V(14)= -Force[4] - Force[1] - Force[3];
00702         V(15)= Force[4] - Force[0] - Force[2];
00703 
00704         return V;
00705 }
00706 
00707 const Vector &
00708 Joint2D::getResistingForceIncInertia()
00709 {
00710         return this->getResistingForce();
00711 }
00712 
00713 
00714 
00715 int Joint2D::displaySelf(Renderer &theViewer, int displayMode, float fact)
00716 {
00717         // first determine the four corner points of the element based on
00718         // the display factor (a measure of the distorted image)
00719         // store this information in 2 3d vectors v1 and v2
00720 
00721         const Vector &node1Crd = theNodes[0]->getCrds();
00722         const Vector &node2Crd = theNodes[1]->getCrds();        
00723         const Vector &node3Crd = theNodes[2]->getCrds();
00724         const Vector &node4Crd = theNodes[3]->getCrds();
00725 
00726         const Vector &node1Disp = theNodes[0]->getDisp();
00727         const Vector &node2Disp = theNodes[1]->getDisp();    
00728         const Vector &node3Disp = theNodes[2]->getDisp();
00729         const Vector &node4Disp = theNodes[3]->getDisp();  
00730 
00731         static Vector v1(3);
00732         static Vector v2(3);
00733         static Vector v3(3);
00734         static Vector v4(3);
00735         
00736         // calculate the current coordinates of four external nodes
00737         for (int i=0; i<2; i++) 
00738     {
00739                 v1(i) = node1Crd(i)+node1Disp(i)*fact;
00740                 v2(i) = node2Crd(i)+node2Disp(i)*fact;
00741                 v3(i) = node3Crd(i)+node3Disp(i)*fact;
00742                 v4(i) = node4Crd(i)+node4Disp(i)*fact;
00743         }
00744 
00745         // draw the center lines
00746         int dummy;
00747         dummy = theViewer.drawLine(v1, v3, 1.0, 1.0);
00748         dummy = theViewer.drawLine(v2, v4, 1.0, 1.0);
00749         
00750         // calculate four corners of the element
00751         Vector vb(3);
00752         Vector vc(3);
00753 
00754         vb = v1 - v3;
00755         vc = v2 - v4;
00756 
00757         v1 = v3 - 0.5 * vc;
00758         v2 = v1 + vb;
00759         v3 = v2 + vc;
00760         v4 = v1 + vc;
00761         
00762         dummy = theViewer.drawLine(v1, v2, 1.0, 1.0);
00763         dummy = theViewer.drawLine(v2, v3, 1.0, 1.0);
00764         dummy = theViewer.drawLine(v3, v4, 1.0, 1.0);
00765         dummy = theViewer.drawLine(v4, v1, 1.0, 1.0);
00766 
00767         return 0;
00768 
00769 }
00770 
00771 
00772 //most-probably requires to be overridden
00773 Response* Joint2D::setResponse(const char **argv, int argc, Information &eleInformation, OPS_Stream &output)
00774 {
00775 //
00776 // we compare argv[0] for known response types for the Truss
00777 //
00778         if (strcmp(argv[0],"node") == 0 || strcmp(argv[0],"internalNode") == 0 )
00779     return new ElementResponse(this, 1, Vector(4));
00780 
00781         else if (strcmp(argv[0],"size") == 0 || strcmp(argv[0],"jointSize") == 0 )
00782     return new ElementResponse(this, 2, Vector(2));
00783 
00784         else if (strcmp(argv[0],"moment") == 0 || strcmp(argv[0],"-moment") == 0 
00785                 || strcmp(argv[0],"force") == 0 || strcmp(argv[0],"-force") == 0 )
00786     return new ElementResponse(this, 3, Vector(5));
00787 
00788         else if (strcmp(argv[0],"defo") == 0 || strcmp(argv[0],"deformations") == 0 ||
00789            strcmp(argv[0],"deformation") == 0 )
00790     return new ElementResponse(this, 4, Vector(5));
00791 
00792         else if (strcmp(argv[0],"defoANDforce") == 0 || strcmp(argv[0],"deformationANDforce") == 0 ||
00793            strcmp(argv[0],"deformationsANDforces") == 0 )
00794     return new ElementResponse(this, 5, Vector(10));
00795 
00796         else if ( strcmp(argv[0],"stiff") == 0 || strcmp(argv[0],"stiffness") == 0 )
00797     return new ElementResponse(this, 6, Matrix(16,16) );
00798         
00799         else if (strcmp(argv[0],"plasticRotation") == 0 || strcmp(argv[0],"plasticDeformation") == 0)
00800                 return new ElementResponse(this, 7, Vector(5));
00801 
00802         else if ( strcmp(argv[0],"damage") == 0 || strcmp(argv[0],"damages") == 0 ||
00803                 strcmp(argv[0],"-damage") == 0 || strcmp(argv[0],"-damages") == 0)
00804                 return new ElementResponse(this, 8, Vector(5));
00805         // material response
00806         else if ( (strcmp(argv[0],"spring")==0) || (strcmp(argv[0],"-spring") == 0) ||
00807                 (strcmp(argv[0],"material")==0) || (strcmp(argv[0],"-material") == 0) ) {
00808                 int materialNum = atoi(argv[1]) - 1;
00809                 
00810                 if (materialNum >= 0 && materialNum < 5)
00811                         if (theSprings[materialNum] != 0)
00812                           return theSprings[materialNum]->setResponse(&argv[2], argc-2, eleInformation, output);
00813         }
00814 
00815         else 
00816                 return 0;
00817         
00818 }
00819 
00820 int Joint2D::getResponse(int responseID, Information &eleInformation)
00821 {
00822         switch (responseID) {
00823         case -1:
00824                 return -1;
00825         
00826         case 1:
00827                 if(eleInformation.theVector!=0)
00828                 {
00829                         const Vector& disp = theNodes[4]->getTrialDisp();
00830                         (*(eleInformation.theVector))(0) = disp(0);
00831                         (*(eleInformation.theVector))(1) = disp(1);
00832                         (*(eleInformation.theVector))(2) = disp(2);
00833                         (*(eleInformation.theVector))(3) = disp(3);
00834                 }
00835                 return 0;
00836 
00837         case 2:
00838                 if(eleInformation.theVector!=0)
00839                 {
00840                         const Vector &node1Crd = theNodes[0]->getCrds();
00841                         const Vector &node2Crd = theNodes[1]->getCrds();        
00842                         const Vector &node3Crd = theNodes[2]->getCrds();
00843                         const Vector &node4Crd = theNodes[3]->getCrds();
00844 
00845                         const Vector &node1Disp = theNodes[0]->getDisp();
00846                         const Vector &node2Disp = theNodes[1]->getDisp();    
00847                         const Vector &node3Disp = theNodes[2]->getDisp();
00848                         const Vector &node4Disp = theNodes[3]->getDisp();  
00849 
00850                         Vector v1(2);
00851                         Vector v2(2);
00852                         Vector v3(2);
00853                         Vector v4(2);
00854         
00855                         // calculate the current coordinates of four external nodes
00856                         for (int i=0; i<2; i++) 
00857                     {
00858                                 v1(i) = node1Crd(i)+node1Disp(i);
00859                                 v2(i) = node2Crd(i)+node2Disp(i);
00860                                 v3(i) = node3Crd(i)+node3Disp(i);
00861                                 v4(i) = node4Crd(i)+node4Disp(i);
00862                         }
00863                         
00864                         v3 = v3 - v1;
00865                         v4 = v4 - v2;
00866 
00867                         v1(0) = v3.Norm();
00868                         v1(1) = v4.Norm();
00869 
00870                         *(eleInformation.theVector) = v1;
00871                 }
00872                 return 0;
00873 
00874         case 3:
00875                 if( eleInformation.theVector != 0 )
00876                 {
00877                         for ( int i =0 ; i<5 ; i++ )
00878                         {
00879                                 (*(eleInformation.theVector))(i) = 0.0;
00880                                 if ( theSprings[i] != NULL ) 
00881                                         (*(eleInformation.theVector))(i) = theSprings[i]->getStress();
00882                         }
00883                 }
00884                 return 0;
00885 
00886         case 4:
00887                 if(eleInformation.theVector!=0)
00888                 {
00889                         for ( int i =0 ; i<5 ; i++ )
00890                         {
00891                                 (*(eleInformation.theVector))(i) = 0.0;
00892                                 if ( theSprings[i] != NULL ) 
00893                                         (*(eleInformation.theVector))(i) = theSprings[i]->getStrain();
00894                         }
00895                 }
00896                 return 0;
00897 
00898         case 5:
00899                 if(eleInformation.theVector!=0)
00900                 {
00901                         for ( int i =0 ; i<5 ; i++ )
00902                         {
00903                                 (*(eleInformation.theVector))(i) = 0.0;
00904                                 (*(eleInformation.theVector))(i+5) = 0.0;
00905                                 if ( theSprings[i] != NULL )
00906                                 {
00907                                         (*(eleInformation.theVector))(i) = theSprings[i]->getStrain();
00908                                         (*(eleInformation.theVector))(i+5) = theSprings[i]->getStress();
00909                                 }
00910                         }
00911                 }
00912                 return 0;
00913 
00914         case 6:
00915                 return eleInformation.setMatrix(this->getTangentStiff());
00916         
00917         case 7:
00918                 if(eleInformation.theVector!=0)
00919                 {
00920                         for ( int i=0 ; i<5 ; i++ )
00921                         {
00922                                 (*(eleInformation.theVector))(i) = 0.0;
00923                                 if ( theSprings[i] != NULL && theSprings[i]->getInitialTangent() != 0.0 )
00924                                 {
00925                                         (*(eleInformation.theVector))(i) = 
00926                                                 theSprings[i]->getStrain() - theSprings[i]->getStress()/theSprings[i]->getInitialTangent();
00927                                 }
00928                                 
00929                         }                       
00930                 }
00931                 return 0;
00932 
00933         case 8:
00934                 if(eleInformation.theVector!=0)
00935                 {
00936                         for ( int i=0 ; i<5 ; i++ )
00937                         {
00938                                 (*(eleInformation.theVector))(i) = 0.0;
00939                                 if ( theDamages[i] != NULL ) {
00940                                         (*(eleInformation.theVector))(i) = theDamages[i]->getDamage();
00941                                 }
00942                         }
00943                 }
00944                 return 0;
00945         
00946         default:
00947                 return -1;
00948         }
00949 }
00950 
00951 
00952 int Joint2D::sendSelf(int commitTag, Channel &theChannel)
00953 {
00954   int res;
00955   int i;
00956   int dataTag = this->getDbTag();
00957   
00958   static ID data(19);
00959   data(0) = this->getTag();
00960   data(1) = numDof;
00961   
00962   if (ExternalNodes.Size() != 0 && nodeDbTag == 0) nodeDbTag = theChannel.getDbTag();
00963   if (InternalConstraints.Size() != 0 && dofDbTag == 0) dofDbTag = theChannel.getDbTag();
00964   data(2) = nodeDbTag;
00965   data(3) = dofDbTag;
00966   
00967   // sending Sparing class and Db tags
00968   for (i=0 ; i<5 ; i++) {
00969     data( i+4 ) = fixedEnd[i];
00970     if ( theSprings[i] != NULL )
00971       {
00972         data( i+9 ) = theSprings[i]->getClassTag();
00973         int SpringDbTag = theSprings[i]->getDbTag();
00974         if (SpringDbTag == 0) {
00975           SpringDbTag = theChannel.getDbTag();
00976           if (SpringDbTag != 0)
00977             theSprings[i]->setDbTag(SpringDbTag);
00978                         }
00979         data(i+14) = SpringDbTag;
00980       } else
00981         {
00982           data( i+9 ) = 0;
00983           data( i+14 ) = 0;
00984         }
00985   }
00986   
00987   // send the ID vector
00988   
00989   res = theChannel.sendID(dataTag, commitTag, data);
00990   if (res < 0) {
00991     opserr << "WARNING Joint2D::sendSelf() - " << this->getTag() << "failed to send ID\n";
00992     return -1;
00993   }
00994   
00995   // sends the tags of it's external nodes
00996   res = theChannel.sendID(nodeDbTag, commitTag, ExternalNodes);
00997   if (res < 0) {
00998     opserr << "WARNING Joint2D::sendSelf() - " << this->getTag()<< " failed to send Vector\n";
00999     return -2;
01000   }
01001   
01002   
01003   // sends the tags of it's internal constraints
01004   res = theChannel.sendID(dofDbTag, commitTag, InternalConstraints);
01005   if (res < 0) {
01006     opserr << "WARNING Joint2D::sendSelf() - %d failed to send Vector\n",this->getTag();
01007     return -2;
01008   }
01009   
01010   
01011   // finally send the materials one by one
01012   
01013   for ( i=0 ; i<5 ; i++ ) {
01014     if ( theSprings[i] != NULL ) {
01015       res = theSprings[i]->sendSelf(commitTag, theChannel);
01016       if (res < 0) {
01017         opserr << "WARNING Joint2D::sendSelf() - "<< this->getTag() << " failed to send its Spring " << (i+1) << " material\n";
01018         return -3;
01019       }
01020     }
01021   }
01022   
01023   return 0;
01024 }
01025 
01026 int Joint2D::recvSelf(int commitTag, Channel &theChannel, FEM_ObjectBroker &theBroker)
01027 {
01028   
01029   int res;
01030   int dataTag = this->getDbTag();
01031   
01032   static ID data(19);
01033   res = theChannel.recvID(dataTag, commitTag, data);
01034   if (res < 0) {
01035     opserr << "WARNING Joint2D::recvSelf() - failed to receive Vector\n";
01036     return -1;
01037   }
01038   
01039   this->setTag((int)data(0));
01040   numDof = data(1);
01041   nodeDbTag = data(2);
01042   dofDbTag = data(3);
01043   
01044   // Receving Springs
01045   for (int i=0 ; i<5 ; i++) {
01046     fixedEnd[i] = data( i+4 );
01047     int SpringClass = data( i+9 );
01048     int SpringDb = data( i+14 );
01049     
01050     if ( SpringClass != 0 && SpringDb != 0  && fixedEnd[i] == 0 )
01051       {
01052         // check if we have a material object already & if we do if of right type
01053         if ((theSprings[i] == 0) || (theSprings[i]->getClassTag() != SpringClass)) {
01054           // if old one .. delete it
01055           if (theSprings[i] != 0)
01056                                         delete theSprings[i];
01057           // create a new material object
01058           theSprings[i] = theBroker.getNewUniaxialMaterial(SpringClass);
01059           if (theSprings[i] == 0) {
01060             opserr << "WARNING Joint2D::recvSelf() - " << (i+1) << " failed to get a blank Material of type " << this->getTag() << " for Spring " << SpringClass << "\n";
01061             return -3;
01062           }
01063         }
01064         
01065         theSprings[i]->setDbTag(SpringDb); // note: we set the dbTag before we receive the material
01066         res = theSprings[i]->recvSelf(commitTag, theChannel, theBroker);
01067         if (res < 0) {
01068           opserr << "WARNING Joint2D::recvSelf() - " << this->getTag() << " failed to receive its Material for Spring " << (i+1) << "\n";
01069           return -3;
01070         }
01071       }
01072     else theSprings[i] = NULL;
01073   }
01074   
01075   
01076   // receives the tags of it's external nodes
01077   res = theChannel.recvID(nodeDbTag, commitTag, ExternalNodes);
01078   if (res < 0) {
01079     opserr << "WARNING Joint2D::recvSelf() - " << this->getTag() << " failed to receive external nodes\n" ;
01080     return -2;
01081   }
01082   
01083   
01084   // receives the tags of it's constraint tags
01085   res = theChannel.recvID(dofDbTag, commitTag, InternalConstraints);
01086   if (res < 0) {
01087     opserr << "WARNING Joint2D::recvSelf() - " << this->getTag() << " failed to receive internal constraints\n";
01088     return -2;
01089   }
01090   
01091   return 0;
01092 }
01093 
01094 
01095 // AddingSensitivity:BEGIN ///////////////////////////////////
01096 int 
01097 Joint2D::addInertiaLoadSensitivityToUnbalance(const Vector &accel, bool somethingRandomInMotions)
01098 {
01099 
01100   if (theLoadSens == 0) {
01101     theLoadSens = new Vector(numDof);
01102   }
01103   else {
01104     theLoadSens->Zero();
01105   }
01106 
01107   return 0;
01108 }
01109 
01110 
01111 int
01112 Joint2D::setParameter(const char **argv, int argc, Parameter &param)
01113 {
01114   if (argc < 1)
01115     return -1;
01116   
01117   // a material parameter
01118   if (strstr(argv[0],"material") != 0) {
01119 
01120     if (argc < 3)
01121       return -1;
01122 
01123     // Get material tag numbers from user input
01124     int paramMaterialTag = atoi(argv[1]);
01125     if ( paramMaterialTag >= 0 && paramMaterialTag < 5)
01126       if ( theSprings[paramMaterialTag] != NULL )
01127         return theSprings[paramMaterialTag]->setParameter(&argv[2], argc-2, param);
01128 
01129     return -1;
01130   }
01131   
01132   // otherwise parameter is unknown for the Joint2D class
01133   return -1;   
01134 }
01135 
01136 const Matrix &
01137 Joint2D::getKiSensitivity(int gradNumber)
01138 {
01139         K.Zero();
01140     
01141         if (parameterID == 0) {
01142                 // // Nothing here
01143         }
01144         
01145         else {
01146                 double KtangentSensitivity[5] ;
01147                 for ( int i=0 ; i<5 ; i++ ) 
01148                 {
01149                         KtangentSensitivity[i] = 0;
01150                         if ( theSprings[i] != NULL ) 
01151                                 KtangentSensitivity[i] = theSprings[i]->getInitialTangentSensitivity(gradNumber);
01152                 }
01153                 
01154                 K(2,2)  =  KtangentSensitivity[0];
01155                 K(2,15) = -KtangentSensitivity[0];
01156                 K(5,5)  =  KtangentSensitivity[1];
01157                 K(5,14) = -KtangentSensitivity[1];
01158                 K(8,8)  =  KtangentSensitivity[2];
01159                 K(8,15) = -KtangentSensitivity[2];
01160                 K(11,11)=  KtangentSensitivity[3];
01161                 K(11,14)= -KtangentSensitivity[3];
01162                 K(14,5) = -KtangentSensitivity[1];
01163                 K(14,11)= -KtangentSensitivity[3];
01164                 K(14,14)=  KtangentSensitivity[1] + KtangentSensitivity[3] + KtangentSensitivity[4];
01165                 K(14,15)= -KtangentSensitivity[4];
01166                 K(15,2) = -KtangentSensitivity[0];
01167                 K(15,8) = -KtangentSensitivity[2];
01168                 K(15,14)= -KtangentSensitivity[4];
01169                 K(15,15)=  KtangentSensitivity[0] + KtangentSensitivity[2] + KtangentSensitivity[4];
01170         }
01171         
01172         return K;
01173 }
01174 
01175 
01176 const Matrix &
01177 Joint2D::getMassSensitivity(int gradNumber)
01178 {
01179         K.Zero();
01180         return K;
01181 }
01182 
01183 
01184 const Vector &
01185 Joint2D::getResistingForceSensitivity(int gradNumber)
01186 {
01187         this->update();
01188         V.Zero();
01189         
01190         // Compute sensitivity depending on the material
01191         double ForceSensitivity[5] ;
01192         for ( int i=0 ; i<5 ; i++ ) 
01193         {
01194                 ForceSensitivity[i] = 0;
01195                 if ( theSprings[i] != NULL ) ForceSensitivity[i] = theSprings[i]->getStressSensitivity(gradNumber,true);
01196         }
01197 
01198         V(2) = ForceSensitivity[0];
01199         V(5) = ForceSensitivity[1];
01200         V(8) = ForceSensitivity[2];
01201         V(11)= ForceSensitivity[3];
01202         V(14)= -ForceSensitivity[4] - ForceSensitivity[1] - ForceSensitivity[3];
01203         V(15)= ForceSensitivity[4] - ForceSensitivity[0] - ForceSensitivity[2];
01204 
01205         return V;
01206 }
01207 
01208 
01209 int
01210 Joint2D::commitSensitivity(int gradNumber, int numGrads)
01211 {
01212 
01213         double strainSensitivity = 0.0;
01214         // Pass it down to the material
01215         for ( int i=0 ; i<5 ; i++ )
01216                 if ( theSprings[i] != NULL )
01217                         theSprings[i]->commitSensitivity(strainSensitivity, gradNumber, numGrads);
01218 
01219         return 0;
01220 }
01221 
01222 // AddingSensitivity:END /////////////////////////////////////////////

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