Node.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.22 $
00022 // $Date: 2006/09/05 20:46:04 $
00023 // $Source: /usr/local/cvs/OpenSees/SRC/domain/node/Node.cpp,v $
00024                                                                         
00025                                                                         
00026 // Written: fmk 
00027 // Created: 11/96
00028 // Revision: A
00029 //
00030 // This file contains the implementation of the Node class
00031 //
00032 // What: "@(#) Node.h, revA"
00033    
00034 #include <Node.h>
00035 #include <stdlib.h>
00036 
00037 #include <Element.h>
00038 #include <Vector.h>
00039 #include <Matrix.h>
00040 #include <Channel.h>
00041 #include <FEM_ObjectBroker.h>
00042 #include <DOF_Group.h>
00043 #include <Renderer.h>
00044 #include <string.h>
00045 #include <Information.h>
00046 #include <Parameter.h>
00047 
00048 // AddingSensitivity:BEGIN //////////////////////////
00049 #include <Domain.h>
00050 #include <Element.h>
00051 #include <ElementIter.h>
00052 // AddingSensitivity:END ////////////////////////////
00053 
00054 #include <OPS_Globals.h>
00055 
00056 Matrix **Node::theMatrices = 0;
00057 int Node::numMatrices = 0;
00058 
00059 // for FEM_Object Broker to use
00060 Node::Node(int theClassTag)
00061 :DomainComponent(0,theClassTag), 
00062  numberDOF(0), theDOF_GroupPtr(0), 
00063  Crd(0), commitDisp(0), commitVel(0), commitAccel(0), 
00064  trialDisp(0), trialVel(0), trialAccel(0), unbalLoad(0), incrDisp(0), 
00065  incrDeltaDisp(0),
00066  disp(0), vel(0), accel(0), dbTag1(0), dbTag2(0), dbTag3(0), dbTag4(0),
00067  R(0), mass(0), unbalLoadWithInertia(0), alphaM(0.0), theEigenvectors(0), 
00068  index(-1), reaction(0)
00069 {
00070   // for FEM_ObjectBroker, recvSelf() must be invoked on object
00071 
00072   // AddingSensitivity:BEGIN /////////////////////////////////////////
00073   dispSensitivity = 0;
00074   velSensitivity = 0;
00075   accSensitivity = 0;
00076   parameterID = 0;
00077   // AddingSensitivity:END ///////////////////////////////////////////
00078 }    
00079 
00080 
00081 Node::Node(int tag, int theClassTag)
00082 :DomainComponent(tag,theClassTag), 
00083  numberDOF(0), theDOF_GroupPtr(0), 
00084  Crd(0), commitDisp(0), commitVel(0), commitAccel(0), 
00085  trialDisp(0), trialVel(0), trialAccel(0), unbalLoad(0), incrDisp(0),
00086  incrDeltaDisp(0), 
00087  disp(0), vel(0), accel(0), dbTag1(0), dbTag2(0), dbTag3(0), dbTag4(0),
00088   R(0), mass(0), unbalLoadWithInertia(0), alphaM(0.0), theEigenvectors(0), 
00089  index(-1), reaction(0)
00090 {
00091   // for subclasses - they must implement all the methods with
00092   // their own data structures.
00093   
00094   // AddingSensitivity:BEGIN /////////////////////////////////////////
00095   dispSensitivity = 0;
00096   velSensitivity = 0;
00097   accSensitivity = 0;
00098   parameterID = 0;
00099   // AddingSensitivity:END ///////////////////////////////////////////
00100 }
00101 
00102 Node::Node(int tag, int ndof, double Crd1)
00103 :DomainComponent(tag,NOD_TAG_Node), 
00104  numberDOF(ndof), theDOF_GroupPtr(0),
00105  Crd(0), commitDisp(0), commitVel(0), commitAccel(0), 
00106  trialDisp(0), trialVel(0), trialAccel(0), unbalLoad(0), incrDisp(0),
00107  incrDeltaDisp(0), 
00108  disp(0), vel(0), accel(0), dbTag1(0), dbTag2(0), dbTag3(0), dbTag4(0),
00109  R(0), mass(0), unbalLoadWithInertia(0), alphaM(0.0), theEigenvectors(0), 
00110  index(-1), reaction(0)
00111 {
00112   // AddingSensitivity:BEGIN /////////////////////////////////////////
00113   dispSensitivity = 0;
00114   velSensitivity = 0;
00115   accSensitivity = 0;
00116   parameterID = 0;
00117   // AddingSensitivity:END ///////////////////////////////////////////
00118   
00119   Crd = new Vector(1);
00120   (*Crd)(0) = Crd1;
00121   
00122   index = -1;
00123   if (numMatrices != 0) {
00124     for (int i=0; i<numMatrices; i++)
00125       if (theMatrices[i]->noRows() == ndof) {
00126         index = i;
00127         i = numMatrices;
00128       }
00129   }
00130   if (index == -1) {
00131     Matrix **nextMatrices = new Matrix *[numMatrices+1];
00132     if (nextMatrices == 0) {
00133       opserr << "Element::getTheMatrix - out of memory\n";
00134       exit(-1);
00135     }
00136     for (int j=0; j<numMatrices; j++)
00137       nextMatrices[j] = theMatrices[j];
00138     Matrix *theMatrix = new Matrix(ndof, ndof);
00139     if (theMatrix == 0) {
00140       opserr << "Element::getTheMatrix - out of memory\n";
00141       exit(-1);
00142     }
00143     nextMatrices[numMatrices] = theMatrix;
00144     if (numMatrices != 0) 
00145       delete [] theMatrices;
00146     index = numMatrices;
00147     numMatrices++;
00148     theMatrices = nextMatrices;
00149   }
00150 }
00151 
00152 
00153 //  Node(int tag, int ndof, double Crd1, double yCrd);
00154 //      constructor for 2d nodes
00155 Node::Node(int tag, int ndof, double Crd1, double Crd2)
00156 :DomainComponent(tag,NOD_TAG_Node), 
00157  numberDOF(ndof), theDOF_GroupPtr(0),
00158  Crd(0), commitDisp(0), commitVel(0), commitAccel(0), 
00159  trialDisp(0), trialVel(0), trialAccel(0), unbalLoad(0), incrDisp(0),
00160  incrDeltaDisp(0), 
00161  disp(0), vel(0), accel(0), dbTag1(0), dbTag2(0), dbTag3(0), dbTag4(0),
00162  R(0), mass(0), unbalLoadWithInertia(0), alphaM(0.0), theEigenvectors(0),
00163  reaction(0)
00164 {
00165   // AddingSensitivity:BEGIN /////////////////////////////////////////
00166   dispSensitivity = 0;
00167   velSensitivity = 0;
00168   accSensitivity = 0;
00169   parameterID = 0;
00170   // AddingSensitivity:END ///////////////////////////////////////////
00171 
00172   Crd = new Vector(2);
00173   (*Crd)(0) = Crd1;
00174   (*Crd)(1) = Crd2;
00175   
00176   index = -1;
00177   if (numMatrices != 0) {
00178     for (int i=0; i<numMatrices; i++)
00179       if (theMatrices[i]->noRows() == ndof) {
00180         index = i;
00181         i = numMatrices;
00182       }
00183   }
00184   if (index == -1) {
00185     Matrix **nextMatrices = new Matrix *[numMatrices+1];
00186     if (nextMatrices == 0) {
00187       opserr << "Element::getTheMatrix - out of memory\n";
00188       exit(-1);
00189     }
00190     for (int j=0; j<numMatrices; j++)
00191       nextMatrices[j] = theMatrices[j];
00192     Matrix *theMatrix = new Matrix(ndof, ndof);
00193     if (theMatrix == 0) {
00194       opserr << "Element::getTheMatrix - out of memory\n";
00195       exit(-1);
00196     }
00197     nextMatrices[numMatrices] = theMatrix;
00198     if (numMatrices != 0) 
00199       delete [] theMatrices;
00200     index = numMatrices;
00201     numMatrices++;
00202     theMatrices = nextMatrices;
00203   }
00204 }
00205 
00206 
00207 //  Node(int tag, int ndof, double Crd1, double Crd2, double zCrd);
00208 //      constructor for 3d nodes
00209 
00210 Node::Node(int tag, int ndof, double Crd1, double Crd2, double Crd3)
00211 :DomainComponent(tag,NOD_TAG_Node), 
00212  numberDOF(ndof), theDOF_GroupPtr(0),
00213  Crd(0), commitDisp(0), commitVel(0), commitAccel(0), 
00214  trialDisp(0), trialVel(0), trialAccel(0), unbalLoad(0), incrDisp(0),
00215  incrDeltaDisp(0), 
00216  disp(0), vel(0), accel(0), dbTag1(0), dbTag2(0), dbTag3(0), dbTag4(0),
00217  R(0), mass(0), unbalLoadWithInertia(0), alphaM(0.0), theEigenvectors(0),
00218  reaction(0)
00219 {
00220   // AddingSensitivity:BEGIN /////////////////////////////////////////
00221   dispSensitivity = 0;
00222   velSensitivity = 0;
00223   accSensitivity = 0;
00224   parameterID = 0;
00225   // AddingSensitivity:END ///////////////////////////////////////////
00226   
00227   Crd = new Vector(3);
00228   (*Crd)(0) = Crd1;
00229   (*Crd)(1) = Crd2;
00230   (*Crd)(2) = Crd3;    
00231   
00232   index = -1;
00233   if (numMatrices != 0) {
00234     for (int i=0; i<numMatrices; i++)
00235       if (theMatrices[i]->noRows() == ndof) {
00236         index = i;
00237         i = numMatrices;
00238       }
00239   }
00240   if (index == -1) {
00241     Matrix **nextMatrices = new Matrix *[numMatrices+1];
00242     if (nextMatrices == 0) {
00243       opserr << "Element::getTheMatrix - out of memory\n";
00244       exit(-1);
00245     }
00246     for (int j=0; j<numMatrices; j++)
00247       nextMatrices[j] = theMatrices[j];
00248     Matrix *theMatrix = new Matrix(ndof, ndof);
00249     if (theMatrix == 0) {
00250       opserr << "Element::getTheMatrix - out of memory\n";
00251       exit(-1);
00252     }
00253     nextMatrices[numMatrices] = theMatrix;
00254     if (numMatrices != 0) 
00255       delete [] theMatrices;
00256     index = numMatrices;
00257     numMatrices++;
00258     theMatrices = nextMatrices;
00259   }
00260 }
00261 
00262 
00263 // used for domain decomposition & external nodes
00264 //  copy everything but the mass 
00265 //  we should really set the mass to 0.0
00266 Node::Node(const Node &otherNode, bool copyMass)
00267 :DomainComponent(otherNode.getTag(),NOD_TAG_Node), 
00268  numberDOF(otherNode.numberDOF), theDOF_GroupPtr(0),
00269  Crd(0), commitDisp(0), commitVel(0), commitAccel(0), 
00270  trialDisp(0), trialVel(0), trialAccel(0), unbalLoad(0), incrDisp(0),
00271  incrDeltaDisp(0), 
00272  disp(0), vel(0), accel(0), dbTag1(0), dbTag2(0), dbTag3(0), dbTag4(0),
00273  R(0), mass(0), unbalLoadWithInertia(0), alphaM(0.0), theEigenvectors(0),
00274  reaction(0)
00275 {
00276   // AddingSensitivity:BEGIN /////////////////////////////////////////
00277   dispSensitivity = 0;
00278   velSensitivity = 0;
00279   accSensitivity = 0;
00280   parameterID = 0;
00281   // AddingSensitivity:END ///////////////////////////////////////////
00282 
00283   Crd = new Vector(otherNode.getCrds());
00284   if (Crd == 0) {
00285     opserr << " FATAL Node::Node(node *) - ran out of memory for Crd\n";
00286     exit(-1);
00287   }
00288 
00289   if (otherNode.commitDisp != 0) {
00290     if (this->createDisp() < 0) {
00291       opserr << " FATAL Node::Node(node *) - ran out of memory for displacement\n";
00292       exit(-1);
00293     }
00294     for (int i=0; i<4*numberDOF; i++)
00295       disp[i] = otherNode.disp[i];
00296   }    
00297   
00298   if (otherNode.commitVel != 0) {
00299     if (this->createVel() < 0) {
00300       opserr << " FATAL Node::Node(node *) - ran out of memory for velocity\n";
00301       exit(-1);
00302     }
00303     for (int i=0; i<2*numberDOF; i++)
00304       vel[i] = otherNode.vel[i];
00305   }    
00306   
00307   if (otherNode.commitAccel != 0) {
00308     if (this->createAccel() < 0) {
00309       opserr << " FATAL Node::Node(node *) - ran out of memory for acceleration\n";
00310       exit(-1);
00311     }
00312     for (int i=0; i<2*numberDOF; i++)
00313       accel[i] = otherNode.accel[i];
00314   }    
00315   
00316   
00317   if (otherNode.unbalLoad != 0){
00318     unbalLoad = new Vector(*(otherNode.unbalLoad));    
00319     if (unbalLoad == 0) {
00320       opserr << " FATAL Node::Node(node *) - ran out of memory for Load\n";
00321       exit(-1);
00322     }
00323     unbalLoad->Zero();
00324   }    
00325 
00326   if (otherNode.mass != 0 && copyMass == true) {
00327     mass = new Matrix(*(otherNode.mass)) ;
00328     if (mass == 0) {
00329       opserr << " FATAL Node::Node(node *) - ran out of memory for mass\n";
00330       exit(-1);
00331     }
00332   }
00333 
00334   if (otherNode.R != 0) {
00335     R = new Matrix(*(otherNode.R));
00336     if (R == 0) {
00337       opserr << " FATAL Node::Node(node *) - ran out of memory for R\n";
00338       exit(-1);
00339     }
00340   }
00341 
00342   index = -1;
00343   if (numMatrices != 0) {
00344     for (int i=0; i<numMatrices; i++)
00345       if (theMatrices[i]->noRows() == numberDOF) {
00346         index = i;
00347         i = numMatrices;
00348       }
00349   }
00350   if (index == -1) {
00351     Matrix **nextMatrices = new Matrix *[numMatrices+1];
00352     if (nextMatrices == 0) {
00353       opserr << "Element::getTheMatrix - out of memory\n";
00354       exit(-1);
00355     }
00356     for (int j=0; j<numMatrices; j++)
00357       nextMatrices[j] = theMatrices[j];
00358     Matrix *theMatrix = new Matrix(numberDOF, numberDOF);
00359     if (theMatrix == 0) {
00360       opserr << "Element::getTheMatrix - out of memory\n";
00361       exit(-1);
00362     }
00363     nextMatrices[numMatrices] = theMatrix;
00364     if (numMatrices != 0) 
00365       delete [] theMatrices;
00366     index = numMatrices;
00367     numMatrices++;
00368     theMatrices = nextMatrices;
00369   }  
00370 }
00371 
00372 
00373 // ~Node():
00374 //      destructor
00375 
00376 Node::~Node()
00377 {
00378     // delete anything that we created with new
00379     if (Crd != 0)
00380         delete Crd;
00381 
00382     if (commitDisp != 0)
00383         delete commitDisp;
00384 
00385     if (commitVel != 0)
00386         delete commitVel;
00387 
00388     if (commitAccel != 0)
00389         delete commitAccel;
00390 
00391     if (trialDisp != 0)
00392         delete trialDisp;
00393 
00394     if (trialVel != 0)
00395         delete trialVel;
00396 
00397     if (trialAccel != 0)
00398         delete trialAccel;
00399 
00400     if (incrDisp != 0)
00401         delete incrDisp;
00402     
00403     if (incrDeltaDisp != 0)
00404         delete incrDeltaDisp;    
00405     
00406     if (unbalLoad != 0)
00407         delete unbalLoad;
00408     
00409     if (disp != 0)
00410         delete [] disp;
00411 
00412     if (vel != 0)
00413         delete [] vel;
00414 
00415     if (accel != 0)
00416         delete [] accel;
00417 
00418     if (mass != 0)
00419         delete mass;
00420     
00421     if (R != 0)
00422         delete R;
00423 
00424     if (unbalLoadWithInertia != 0)
00425       delete unbalLoadWithInertia;
00426 
00427     if (theEigenvectors != 0)
00428       delete theEigenvectors;
00429 
00430     // AddingSensitivity:BEGIN ///////////////////////////////////////
00431     if (dispSensitivity != 0)
00432       delete dispSensitivity;
00433     if (velSensitivity != 0)
00434         delete velSensitivity;
00435     if (accSensitivity != 0)
00436       delete accSensitivity;
00437     // AddingSensitivity:END /////////////////////////////////////////
00438 
00439     if (reaction != 0)
00440       delete reaction;
00441 
00442     if (theDOF_GroupPtr != 0)
00443       theDOF_GroupPtr->resetNodePtr();
00444 }
00445 
00446 
00447 int
00448 Node::getNumberDOF(void) const
00449 {
00450     // return the number of dof
00451     return  numberDOF;
00452 }
00453 
00454 
00455 void
00456 Node::setDOF_GroupPtr(DOF_Group *theDOF_Grp)
00457 {
00458     // set the DOF_Group pointer
00459     theDOF_GroupPtr = theDOF_Grp;
00460 }
00461 
00462 
00463 DOF_Group *
00464 Node::getDOF_GroupPtr(void)
00465 {
00466     // return the DOF_Group pointer
00467     return theDOF_GroupPtr;
00468 }
00469 
00470 
00471 const Vector &
00472 Node::getCrds() const
00473 {
00474     // return the vector of nodal coordinates
00475     return *Crd;
00476 }
00477 
00478 
00479 
00480 
00481 const Vector &
00482 Node::getDisp(void) 
00483 {
00484     // construct memory and Vectors for trial and committed
00485     // displacement on first call to this method, getTrialDisp()
00486     // setTrialDisp() or incrTrialDisp()
00487     if (commitDisp == 0) {
00488         if (this->createDisp() < 0) {
00489             opserr << "FATAL Node::getDisp() -- ran out of memory\n";
00490             exit(-1);
00491         }
00492     }
00493     
00494     // return the committed disp
00495     return *commitDisp;
00496 }
00497 
00498 const Vector &
00499 Node::getVel(void) 
00500 {
00501     // construct memory and Vectors for trial and committed
00502     // velocity on first call to this method, getTrialVel()
00503     // setTrialVel() or incrTrialVel()    
00504     if (commitVel == 0) {
00505         if (this->createVel() < 0) {
00506             opserr << "FATAL Node::getVel() -- ran out of memory\n";
00507             exit(-1);
00508         }
00509     }    
00510 
00511     // return the velocity
00512     return *commitVel;    
00513 }
00514 
00515 
00516 const Vector &
00517 Node::getAccel(void) 
00518 {
00519     // construct memory and Vectors for trial and committed
00520     // accel on first call to this method, getTrialAccel()
00521     // setTrialAccel() or incrTrialAccel()        
00522     if (commitAccel == 0) {
00523         if (this->createAccel() < 0) {
00524             opserr << "FATAL Node::getAccel() -- ran out of memory\n";
00525             exit(-1);
00526         }
00527     }
00528 
00529     return *commitAccel;    
00530 }
00531 
00532 
00533 /* *********************************************************************
00534 **
00535 **   Methods to return the trial response quantities similar to committed
00536 **
00537 ** *********************************************************************/
00538 
00539 const Vector &
00540 Node::getTrialDisp(void) 
00541 {
00542     if (trialDisp == 0) {
00543         if (this->createDisp() < 0) {
00544             opserr << "FATAL Node::getTrialDisp() -- ran out of memory\n";
00545             exit(-1);
00546         }
00547     }    
00548 
00549     return *trialDisp;
00550 }
00551 
00552 
00553 
00554 const Vector &
00555 Node::getTrialVel(void) 
00556 {
00557     if (trialVel == 0) {
00558         if (this->createVel() < 0) {
00559             opserr << "FATAL Node::getTrialVel() -- ran out of memory\n";
00560             exit(-1);
00561         }
00562     }    
00563 
00564     return *trialVel;
00565 }
00566 
00567 
00568 
00569 const Vector &
00570 Node::getTrialAccel(void) 
00571 {
00572     if (trialAccel == 0) {
00573         if (this->createAccel() < 0) {
00574             opserr << "FATAL Node::getTrialAccel() - ran out of memory\n";
00575             exit(0);
00576         }
00577     }    
00578     return *trialAccel;
00579 }
00580 
00581 const Vector &
00582 Node::getIncrDisp(void) 
00583 {
00584     if (incrDisp == 0) {
00585         if (this->createDisp() < 0) {
00586             opserr << "FATAL Node::getTrialDisp() -- ran out of memory\n";
00587             exit(-1);
00588         }
00589     }    
00590 
00591     return *incrDisp;
00592 }
00593 
00594 const Vector &
00595 Node::getIncrDeltaDisp(void) 
00596 {
00597     if (incrDeltaDisp == 0) {
00598         if (this->createDisp() < 0) {
00599             opserr << "FATAL Node::getTrialDisp() -- ran out of memory\n";
00600             exit(-1);
00601         }
00602     }    
00603 
00604     return *incrDeltaDisp;
00605 }
00606 
00607 
00608 int
00609 Node::setTrialDisp(double value, int dof)
00610 {
00611     // check vector arg is of correct size
00612     if (dof < 0 || dof >=  numberDOF) {
00613       opserr << "WARNING Node::setTrialDisp() - incompatable sizes\n";
00614       return -2;
00615     }    
00616 
00617     // construct memory and Vectors for trial and committed
00618     // accel on first call to this method, getTrialDisp(),
00619     // getDisp(), or incrTrialDisp()        
00620     if (trialDisp == 0) {
00621         if (this->createDisp() < 0) {
00622             opserr << "FATAL Node::setTrialDisp() - ran out of memory\n";
00623             exit(-1);
00624         }    
00625     }
00626 
00627     // perform the assignment .. we dont't go through Vector interface
00628     // as we are sure of size and this way is quicker
00629     double tDisp = value;
00630     disp[dof+2*numberDOF] = tDisp - disp[dof+numberDOF];
00631     disp[dof+3*numberDOF] = tDisp - disp[dof];  
00632     disp[dof] = tDisp;
00633 
00634     return 0;
00635 }
00636 
00637 int
00638 Node::setTrialDisp(const Vector &newTrialDisp)
00639 {
00640     // check vector arg is of correct size
00641     if (newTrialDisp.Size() != numberDOF) {
00642             opserr << "WARNING Node::setTrialDisp() - incompatable sizes\n";
00643             return -2;
00644         }    
00645 
00646     // construct memory and Vectors for trial and committed
00647     // accel on first call to this method, getTrialDisp(),
00648     // getDisp(), or incrTrialDisp()        
00649     if (trialDisp == 0) {
00650         if (this->createDisp() < 0) {
00651             opserr << "FATAL Node::setTrialDisp() - ran out of memory\n";
00652             exit(-1);
00653         }    
00654     }
00655 
00656     // perform the assignment .. we dont't go through Vector interface
00657     // as we are sure of size and this way is quicker
00658     for (int i=0; i<numberDOF; i++) {
00659         double tDisp = newTrialDisp(i);
00660         disp[i+2*numberDOF] = tDisp - disp[i+numberDOF];
00661         disp[i+3*numberDOF] = tDisp - disp[i];  
00662         disp[i] = tDisp;
00663     }
00664 
00665     return 0;
00666 }
00667 
00668 int
00669 Node::setTrialVel(const Vector &newTrialVel)
00670 {
00671     // check vector arg is of correct size
00672     if (newTrialVel.Size() != numberDOF) {
00673             opserr << "WARNING Node::setTrialVel() - incompatable sizes\n";
00674             return -2;
00675     }    
00676 
00677     // construct memory and Vectors for trial and committed
00678     // accel on first call to this method, getTrialVEl(),
00679     // getVEl(), or incrTrialVel()        
00680     if (trialVel == 0) {
00681         if (this->createVel() < 0) {
00682             opserr << "FATAL Node::setTrialVel() - ran out of memory\n";
00683             exit(-1);
00684         }
00685     }      
00686     
00687     // set the trial quantities
00688     for (int i=0; i<numberDOF; i++)
00689         vel[i] = newTrialVel(i);
00690     return 0;
00691 }
00692 
00693 
00694 int
00695 Node::setTrialAccel(const Vector &newTrialAccel)
00696 {
00697     // check vector arg is of correct size
00698     if (newTrialAccel.Size() != numberDOF) {
00699             opserr << "WARNING Node::setTrialAccel() - incompatable sizes\n";
00700             return -2;
00701     }    
00702 
00703     // create a copy if no trial exists    
00704     if (trialAccel == 0) {
00705         if (this->createAccel() < 0) {
00706             opserr << "FATAL Node::setTrialAccel() - ran out of memory\n";
00707             exit(-1);
00708         }
00709     }        
00710     
00711     // use vector assignment otherwise        
00712     for (int i=0; i<numberDOF; i++)
00713         accel[i] = newTrialAccel(i);
00714 
00715     return 0;
00716 }
00717 
00718 int
00719 Node::incrTrialDisp(const Vector &incrDispl)
00720 {
00721     // check vector arg is of correct size
00722     if (incrDispl.Size() != numberDOF) {
00723         opserr << "WARNING Node::incrTrialDisp() - incompatable sizes\n";
00724         return -2;
00725     }    
00726 
00727     // create a copy if no trial exists andd add committed
00728     if (trialDisp == 0) {
00729         if (this->createDisp() < 0) {
00730             opserr << "FATAL Node::incrTrialDisp() - ran out of memory\n";
00731             exit(-1);
00732         }    
00733         for (int i = 0; i<numberDOF; i++) {
00734           double incrDispI = incrDispl(i);
00735           disp[i] = incrDispI;
00736           disp[i+2*numberDOF] = incrDispI;
00737           disp[i+3*numberDOF] = incrDispI;
00738         }
00739         return 0;
00740     }
00741 
00742     // otherwise set trial = incr + trial
00743     for (int i = 0; i<numberDOF; i++) {
00744           double incrDispI = incrDispl(i);
00745           disp[i] += incrDispI;
00746           disp[i+2*numberDOF] += incrDispI;
00747           disp[i+3*numberDOF] = incrDispI;
00748     }
00749 
00750     return 0;
00751 }
00752 
00753 
00754 int
00755 Node::incrTrialVel(const Vector &incrVel)
00756 {
00757     // check vector arg is of correct size
00758     if (incrVel.Size() != numberDOF) {
00759         opserr << "WARNING Node::incrTrialVel() - incompatable sizes\n";
00760         return -2;
00761     }    
00762 
00763     // create Vectors and array if none exist and set trial
00764     if (trialVel == 0) {
00765         if (this->createVel() < 0) {
00766             opserr << "FATAL Node::incrTrialVel - ran out of memory\n";
00767             exit(-1);
00768         }    
00769         for (int i = 0; i<numberDOF; i++)
00770             vel[i] = incrVel(i);
00771 
00772         return 0;
00773     }
00774 
00775     // otherwise set trial = incr + trial
00776     for (int i = 0; i<numberDOF; i++)
00777         vel[i] += incrVel(i);    
00778 
00779     return 0;
00780 }
00781 
00782 
00783 int
00784 Node::incrTrialAccel(const Vector &incrAccel)
00785 {
00786     // check vector arg is of correct size
00787     if (incrAccel.Size() != numberDOF) {
00788         opserr << "WARNING Node::incrTrialAccel() - incompatable sizes\n";
00789         return -2;
00790     }    
00791 
00792     // create a copy if no trial exists andd add committed    
00793     if (trialAccel == 0) {
00794         if (this->createAccel() < 0) {
00795             opserr << "FATAL Node::incrTrialAccel() - ran out of memory\n";
00796             exit(-1);
00797         }    
00798         for (int i = 0; i<numberDOF; i++)
00799             accel[i] = incrAccel(i);
00800 
00801         return 0;
00802     }
00803 
00804     // otherwise set trial = incr + trial
00805     for (int i = 0; i<numberDOF; i++)
00806         accel[i] += incrAccel(i);    
00807 
00808     return 0;
00809 }
00810 
00811 
00812 void 
00813 Node::zeroUnbalancedLoad(void)
00814 {
00815     if (unbalLoad != 0)
00816         unbalLoad->Zero();
00817 }
00818 
00819 int
00820 Node::addUnbalancedLoad(const Vector &add, double fact)
00821 {
00822     // check vector arg is of correct size
00823     if (add.Size() != numberDOF) {
00824         opserr << "Node::addunbalLoad - load to add of incorrect size ";
00825         opserr << add.Size() << " should be " <<  numberDOF << endln;   
00826         return -1;
00827     }
00828 
00829     // if no load yet create it and assign
00830     if (unbalLoad == 0) {
00831         unbalLoad = new Vector(add); 
00832         if (unbalLoad == 0) {
00833             opserr << "FATAL Node::addunbalLoad - ran out of memory\n";
00834             exit(-1);
00835         }
00836         if (fact != 1.0)
00837             (*unbalLoad) *= fact;
00838         return 0;
00839     }
00840 
00841     // add fact*add to the unbalanced load
00842     unbalLoad->addVector(1.0, add,fact);
00843 
00844     return 0;
00845 }
00846 
00847 
00848 
00849 int
00850 Node::addInertiaLoadToUnbalance(const Vector &accelG, double fact)
00851 {
00852   // simply return if node has no mass or R matrix
00853   if (mass == 0 || R == 0)
00854     return 0;
00855 
00856   // otherwise we must determine MR accelG
00857   if (accelG.Size() != R->noCols()) {
00858     opserr << "Node::addInertiaLoadToUnbalance - accelG not of correct dimension";
00859     return -1;
00860   }
00861 
00862   // if no load yet create it and assign
00863   if (unbalLoad == 0) {
00864       unbalLoad = new Vector(numberDOF); 
00865       if (unbalLoad == 0 || unbalLoad->Size() != numberDOF) {
00866           opserr << "FATAL Node::addunbalLoad - ran out of memory\n";
00867           exit(-1);
00868       }  
00869   }
00870 
00871   // form - fact * M*R*accelG and add it to the unbalanced load
00872   //(*unbalLoad) -= ((*mass) * (*R) * accelG)*fact;
00873 
00874   Matrix MR(mass->noRows(), R->noCols());
00875   MR.addMatrixProduct(0.0, *mass, *R, 1.0);
00876   unbalLoad->addMatrixVector(1.0, MR, accelG, -fact);
00877 
00878   return 0;
00879 }
00880 
00881 
00882 
00883 int
00884 Node::addInertiaLoadSensitivityToUnbalance(const Vector &accelG, double fact, bool somethingRandomInMotions)
00885 {
00886   // simply return if node has no mass or R matrix
00887   if (mass == 0 || R == 0)
00888     return 0;
00889 
00890   // otherwise we must determine MR accelG
00891   if (accelG.Size() != R->noCols()) {
00892     opserr << "Node::addInertiaLoadToUnbalance - accelG not of correct dimension";
00893     return -1;
00894   }
00895 
00896   // if no load yet create it and assign
00897   if (unbalLoad == 0) {
00898       unbalLoad = new Vector(numberDOF); 
00899       if (unbalLoad == 0 || unbalLoad->Size() != numberDOF) {
00900           opserr << "FATAL Node::addunbalLoad - ran out of memory\n";
00901           exit(-1);
00902       }  
00903   }
00904 
00905   // form - fact * M*R*accelG and add it to the unbalanced load
00906   //(*unbalLoad) -= ((*mass) * (*R) * accelG)*fact;
00907 
00908 
00909 
00910         Matrix massSens(mass->noRows(),mass->noCols());
00911         if (parameterID != 0) {
00912                 massSens(parameterID-1,parameterID-1) = 1.0;
00913         }
00914 
00915         Matrix MR(mass->noRows(), R->noCols());
00916 
00917         if (somethingRandomInMotions) {
00918                 MR.addMatrixProduct(0.0, *mass, *R, 1.0);
00919         }
00920         else {
00921                 MR.addMatrixProduct(0.0, massSens, *R, 1.0);
00922         }
00923         unbalLoad->addMatrixVector(1.0, MR, accelG, -fact);
00924 
00925   return 0;
00926 }
00927 
00928 
00929 
00930 const Vector &
00931 Node::getUnbalancedLoad(void) 
00932 {
00933     // make sure it was created before we return it
00934     if (unbalLoad == 0) {
00935         unbalLoad = new Vector(numberDOF);
00936         if (unbalLoad == 0 || unbalLoad->Size() != numberDOF) {
00937             opserr << "FATAL Node::getunbalLoad() -- ran out of memory\n";
00938             exit(-1);
00939         }
00940     }
00941 
00942     // return the unbalanced load
00943 
00944     return *unbalLoad;
00945 }
00946 
00947 
00948     
00949 const Vector &
00950 Node::getUnbalancedLoadIncInertia(void) 
00951 {
00952     // make sure it was created before we return it
00953     if (unbalLoadWithInertia == 0) {
00954         unbalLoadWithInertia = new Vector(this->getUnbalancedLoad());
00955         if (unbalLoadWithInertia == 0) {
00956             opserr << "FATAL Node::getunbalLoadWithInertia -- ran out of memory\n";
00957             exit(-1);
00958         }
00959     } else
00960       (*unbalLoadWithInertia) = this->getUnbalancedLoad();
00961 
00962     if (mass != 0) {
00963 
00964       const Vector &theAccel = this->getTrialAccel(); // in case accel not created
00965       unbalLoadWithInertia->addMatrixVector(1.0, *mass, theAccel, -1.0);
00966 
00967       if (alphaM != 0.0) {
00968         const Vector &theVel = this->getTrialVel(); // in case vel not created
00969         unbalLoadWithInertia->addMatrixVector(1.0, *mass, theVel, -alphaM);
00970       }
00971     } 
00972 
00973     return *unbalLoadWithInertia;
00974 }
00975 
00976 
00977 
00978 int
00979 Node::commitState()
00980 {
00981     // check disp exists, if does set commit = trial, incr = 0.0
00982     if (trialDisp != 0) {
00983       for (int i=0; i<numberDOF; i++) {
00984         disp[i+numberDOF] = disp[i];  
00985         disp[i+2*numberDOF] = 0.0;
00986         disp[i+3*numberDOF] = 0.0;
00987       }
00988     }               
00989     
00990     // check vel exists, if does set commit = trial    
00991     if (trialVel != 0) {
00992       for (int i=0; i<numberDOF; i++)
00993         vel[i+numberDOF] = vel[i];
00994     }
00995     
00996     // check accel exists, if does set commit = trial        
00997     if (trialAccel != 0) {
00998       for (int i=0; i<numberDOF; i++)
00999         accel[i+numberDOF] = accel[i];
01000     }
01001 
01002     // if we get here we are done
01003     return 0;
01004 }
01005 
01006 
01007 
01008 int
01009 Node::revertToLastCommit()
01010 {
01011     // check disp exists, if does set trial = last commit, incr = 0
01012     if (disp != 0) {
01013       for (int i=0 ; i<numberDOF; i++) {
01014         disp[i] = disp[i+numberDOF];
01015         disp[i+2*numberDOF] = 0.0;
01016         disp[i+3*numberDOF] = 0.0;
01017       }
01018     }
01019     
01020     // check vel exists, if does set trial = last commit
01021     if (vel != 0) {
01022       for (int i=0 ; i<numberDOF; i++)
01023         vel[i] = vel[numberDOF+i];
01024     }
01025 
01026     // check accel exists, if does set trial = last commit
01027     if (accel != 0) {    
01028       for (int i=0 ; i<numberDOF; i++)
01029         accel[i] = accel[numberDOF+i];
01030     }
01031 
01032     // if we get here we are done
01033     return 0;
01034 }
01035 
01036 
01037 int
01038 Node::revertToStart()
01039 {
01040     // check disp exists, if does set all to zero
01041     if (disp != 0) {
01042       for (int i=0 ; i<4*numberDOF; i++)
01043         disp[i] = 0.0;
01044     }
01045 
01046     // check vel exists, if does set all to zero
01047     if (vel != 0) {
01048       for (int i=0 ; i<2*numberDOF; i++)
01049         vel[i] = 0.0;
01050     }
01051 
01052     // check accel exists, if does set all to zero
01053     if (accel != 0) {    
01054       for (int i=0 ; i<2*numberDOF; i++)
01055         accel[i] = 0.0;
01056     }
01057     
01058     if (unbalLoad != 0) 
01059         (*unbalLoad) *= 0;
01060 
01061 
01062 
01063 
01064 // AddingSensitivity: BEGIN /////////////////////////////////
01065         if (dispSensitivity != 0) 
01066                 dispSensitivity->Zero();
01067         
01068         if (velSensitivity != 0) 
01069                 velSensitivity->Zero();
01070         
01071         if (accSensitivity != 0) 
01072                 accSensitivity->Zero();
01073 // AddingSensitivity: END ///////////////////////////////////
01074 
01075 
01076 
01077     // if we get here we are done
01078     return 0;
01079 }
01080 
01081 
01082 const Matrix &
01083 Node::getMass(void) 
01084 {
01085     // make sure it was created before we return it
01086     if (mass == 0) {
01087       theMatrices[index]->Zero();
01088       return *theMatrices[index];
01089     } else 
01090       return *mass;
01091 }
01092 
01093 
01094 int 
01095 Node::setRayleighDampingFactor(double alpham) {
01096   alphaM = alpham;
01097   return 0;
01098 }
01099 
01100 
01101 const Matrix &
01102 Node::getDamp(void) 
01103 {
01104     // make sure it was created before we return it
01105     if (mass == 0 || alphaM == 0.0) {
01106       theMatrices[index]->Zero();
01107       return *theMatrices[index];
01108     } else {
01109       Matrix &result = *theMatrices[index];
01110       result = *mass;
01111       result *= alphaM;
01112       return result;
01113     } 
01114 }
01115 
01116 
01117 const Matrix &
01118 Node::getDampSensitivity(void) 
01119 {
01120     // make sure it was created before we return it
01121     if (mass == 0 || alphaM == 0.0) {
01122       theMatrices[index]->Zero();
01123       return *theMatrices[index];
01124     } else {
01125       Matrix &result = *theMatrices[index];
01126           result.Zero();
01127       //result = *mass;
01128       //result *= alphaM;
01129       return result;
01130     } 
01131 }
01132 
01133 
01134 int
01135 Node::setMass(const Matrix &newMass)
01136 {
01137     // check right size
01138     if (newMass.noRows() != numberDOF || newMass.noCols() != numberDOF) {
01139         opserr << "Node::setMass - incompatable matrices\n";
01140         return -1;
01141     }   
01142 
01143     // create a matrix if no mass yet set
01144     if (mass == 0) {
01145         mass = new Matrix(newMass);
01146         if (mass == 0 || mass->noRows() != numberDOF) {
01147             opserr << "FATAL Node::setMass - ran out of memory\n";
01148             return -1;
01149         }
01150         return 0;
01151     }
01152 
01153     // assign if mass has already been created
01154     (*mass) = newMass;
01155     
01156     return 0;
01157 }
01158 
01159 
01160 
01161 int 
01162 Node::setNumColR(int numCol)
01163 {
01164   if (R != 0) {
01165     if (R->noCols() != numCol) {
01166       delete R;
01167       R = new Matrix(numberDOF, numCol);
01168     }
01169   } else 
01170     R = new Matrix(numberDOF, numCol);
01171 
01172   if (R == 0 || R->noRows() != numberDOF) {
01173       opserr << "FATAL Node::setNumColR() - out of memory\n";
01174       exit(-1);
01175   }
01176 
01177   R->Zero();
01178   return 0;
01179 }  
01180 
01181 int 
01182 Node::setR(int row, int col, double Value)
01183 {
01184   // ensure R had been set
01185   if (R == 0) {
01186     opserr << "Node:setR() - R has not been initialised\n";
01187     return -1;
01188   }
01189   
01190   // ensure row, col in range (matrix assignment will catch this - extra work)
01191   if (row < 0 || row > numberDOF || col < 0 || col > R->noCols()) {
01192     opserr << "Node:setR() - row, col index out of range\n";
01193     return -1;
01194   }
01195 
01196   // do the assignment
01197   (*R)(row,col) = Value;
01198   return 0;
01199 }
01200 
01201 
01202 
01203 const Vector &
01204 Node::getRV(const Vector &V)
01205 {
01206     // we store the product of RV in unbalLoadWithInertia
01207 
01208     // make sure unbalLoadWithInertia was created, if not create it
01209     if (unbalLoadWithInertia == 0) {
01210         unbalLoadWithInertia = new Vector(numberDOF);
01211         if (unbalLoadWithInertia == 0) {
01212             opserr << "Node::getunbalLoadWithInertia -- ran out of memory\n";
01213             exit(-1);
01214         }
01215     } 
01216     
01217     // see if quick return , i.e. R == 0
01218     if (R == 0) {
01219         unbalLoadWithInertia->Zero();
01220         return *unbalLoadWithInertia;
01221     }
01222     
01223     // check dimesions of R and V
01224     if (R->noCols() != V.Size()) {
01225         opserr << "WARNING Node::getRV() - R and V of incompatable dimesions\n";
01226         opserr << "R: " << *R << "V: " << V;
01227         unbalLoadWithInertia->Zero();
01228         return *unbalLoadWithInertia;
01229     }    
01230 
01231     // determine the product
01232     unbalLoadWithInertia->addMatrixVector(0.0, *R, V, 1.0);
01233     return *unbalLoadWithInertia;
01234 }
01235 
01236 
01237 int 
01238 Node::setNumEigenvectors(int numVectorsToStore)
01239 {
01240   // ensure a positive number of vectors
01241   if (numVectorsToStore <= 0) {
01242     opserr << "Node::setNumEigenvectors() - " << numVectorsToStore << " < 0\n";
01243     return -1;
01244   }    
01245 
01246   // if matrix not yet assigned or not of correct size delete old and create new
01247   if (theEigenvectors == 0 || theEigenvectors->noCols() != numVectorsToStore) {
01248     if (theEigenvectors != 0)
01249       delete theEigenvectors;
01250 
01251 
01252     theEigenvectors = new Matrix(numberDOF, numVectorsToStore);
01253     if (theEigenvectors == 0 || theEigenvectors->noCols() != numVectorsToStore) {
01254       opserr << "Node::setNumEigenvectors() - out of memory\n";
01255       return -2;
01256     }
01257   } else
01258     // zero the eigenvector matrix
01259     theEigenvectors->Zero();
01260   
01261     return 0;
01262 }
01263 int 
01264 Node::setEigenvector(int mode, const Vector &eigenVector)
01265 {
01266   if (theEigenvectors == 0 || theEigenvectors->noCols() < mode) {
01267     opserr << "Node::setEigenvectors() - mode " << mode << " invalid\n";
01268     return -1;
01269   }
01270 
01271   if (eigenVector.Size() != numberDOF) {
01272       opserr << "Node::setEigenvectors() - eigenvector of incorrect size\n";
01273       return -2;
01274   }
01275   // set the values
01276   for (int i=0; i<numberDOF; i++)
01277     (*theEigenvectors)(i, mode-1) = eigenVector(i);
01278 
01279   return 0;
01280 }
01281 const Matrix &
01282 Node::getEigenvectors(void)
01283 {
01284   // check the eigen vectors have been set
01285         if (theEigenvectors == 0) {
01286     opserr << "Node::getEigenvectors() - eigenvectors have not been set\n";
01287         exit(0);
01288         }
01289   
01290   return *theEigenvectors;
01291 }
01292 
01293 
01294 int 
01295 Node::sendSelf(int cTag, Channel &theChannel)
01296 {
01297     int dataTag = this->getDbTag();
01298 
01299     ID data(14);
01300     data(0) = this->getTag(); 
01301     data(1) = numberDOF; 
01302     
01303     // indicate whether vector quantaties have been formed
01304     if (disp == 0)       data(2) = 1; else data(2) = 0;
01305     if (vel == 0)        data(3) = 1; else data(3) = 0;
01306     if (accel == 0)      data(4) = 1; else data(4) = 0;
01307     if (mass == 0)       data(5) = 1; else data(5) = 0;
01308     if (unbalLoad  == 0) data(6) = 1; else data(6) = 0;    
01309     if (R == 0)          
01310         data(12) = 1; 
01311     else {
01312         data(12) = 0;        
01313         data(13) = R->noCols();
01314     }
01315 
01316     data(7) = Crd->Size();
01317 
01318     if (dbTag1 == 0)
01319       dbTag1 = theChannel.getDbTag();
01320     if (dbTag2 == 0)
01321       dbTag2 = theChannel.getDbTag();
01322     if (dbTag3 == 0)
01323       dbTag3 = theChannel.getDbTag();
01324     if (dbTag4 == 0)
01325       dbTag4 = theChannel.getDbTag();
01326 
01327     data(8) = dbTag1;
01328     data(9) = dbTag2;
01329     data(10) = dbTag3;
01330     data(11) = dbTag4;
01331 
01332     int res = 0;
01333 
01334     res = theChannel.sendID(dataTag, cTag, data);
01335     if (res < 0) {
01336       opserr << " Node::sendSelf() - failed to send ID data\n";
01337       return res;
01338     }
01339 
01340     res = theChannel.sendVector(dataTag, cTag, *Crd);
01341     if (res < 0) {
01342       opserr << " Node::sendSelf() - failed to send Vecor data\n";
01343       return res;
01344     }
01345 
01346     if (commitDisp != 0) {
01347         res = theChannel.sendVector(dbTag1, cTag, *commitDisp); 
01348         if (res < 0) {
01349           opserr << " Node::sendSelf() - failed to send Disp data\n";
01350           return res;
01351         }
01352     }
01353 
01354     if (commitVel != 0) {
01355         res = theChannel.sendVector(dbTag2, cTag, *commitVel);          
01356         if (res < 0) {
01357           opserr << " Node::sendSelf() - failed to send Vel data\n";
01358           return res;
01359         }
01360     }
01361 
01362     if (commitAccel != 0) {
01363         res = theChannel.sendVector(dbTag3, cTag, *commitAccel); 
01364         if (res < 0) {
01365           opserr << " Node::sendSelf() - failed to send Accel data\n";
01366           return res;
01367         }
01368     }
01369 
01370     if (mass != 0) {
01371         res = theChannel.sendMatrix(dataTag, cTag, *mass);
01372         if (res < 0) {
01373           opserr << " Node::sendSelf() - failed to send Mass data\n";
01374           return res;
01375         }
01376     }
01377     
01378     if (R != 0) {
01379         res = theChannel.sendMatrix(dataTag, cTag, *R);
01380         if (res < 0) {
01381           opserr << " Node::sendSelf() - failed to send R data\n";
01382           return res;
01383         }
01384     }    
01385 
01386     if (unbalLoad  != 0) {
01387         res = theChannel.sendVector(dbTag4, cTag, *unbalLoad);  
01388         if (res < 0) {
01389           opserr << " Node::sendSelf() - failed to send Load data\n";
01390           return res;
01391         }
01392     }
01393 
01394     // if get here succesfull
01395     return 0;
01396 }
01397 
01398 int 
01399 Node::recvSelf(int cTag, Channel &theChannel, 
01400                FEM_ObjectBroker &theBroker)
01401 {
01402     int res = 0;
01403     int dataTag = this->getDbTag();
01404 
01405     
01406     ID data(14);
01407     res = theChannel.recvID(dataTag, cTag, data);
01408     if (res < 0) {
01409       opserr << "Node::recvSelf() - failed to receive ID data\n";
01410       return res;
01411     }
01412 
01413     this->setTag(data(0));
01414     numberDOF = data(1);
01415     int numberCrd = data(7);
01416 
01417     dbTag1 = data(8);
01418     dbTag2 = data(9);
01419     dbTag3 = data(10);
01420     dbTag4 = data(11);
01421     
01422 
01423     // create a Vector to hold coordinates IF one needed
01424     if (Crd == 0) {
01425       Crd = new Vector(numberCrd);
01426     }
01427 
01428     // check we did not run out of memory
01429     if (Crd == 0) {
01430       opserr << "Node::recvSelf() - out of memory creating Coordinate vector\n";
01431       return -1;
01432     }
01433 
01434     if (theChannel.recvVector(dataTag, cTag, *Crd) < 0) {
01435       opserr << "Node::recvSelf() - failed to receive the Coordinate vector\n";
01436       return -2;
01437     }
01438 
01439     if (data(2) == 0) {
01440       // create the disp vectors if node is a total blank
01441       if (commitDisp == 0)
01442         this->createDisp();
01443 
01444       // recv the committed disp
01445       if (theChannel.recvVector(dbTag1, cTag, *commitDisp) < 0) {
01446         opserr << "Node::recvSelf - failed to receive Disp data\n";
01447         return res;
01448       }
01449 
01450       // set the trial quantities equal to committed
01451       for (int i=0; i<numberDOF; i++)
01452         disp[i] = disp[i+numberDOF];  // set trial equal commited
01453 
01454     } else if (commitDisp != 0) {
01455       // if going back to initial we will just zero the vectors
01456       commitDisp->Zero();
01457       trialDisp->Zero();
01458     }
01459       
01460     
01461     if (data(3) == 0) {
01462       // create the vel vectors if node is a total blank
01463       if (commitVel == 0) 
01464         this->createVel();
01465 
01466       // recv the committed vel
01467       if (theChannel.recvVector(dbTag2, cTag, *commitVel) < 0) {
01468         opserr << "Node::recvSelf - failed to receive Velocity data\n";
01469         return -3;
01470       }
01471 
01472       // set the trial quantity
01473       for (int i=0; i<numberDOF; i++)
01474         vel[i] = vel[i+numberDOF];  // set trial equal commited
01475     }
01476 
01477     if (data(4) == 0) {
01478       // create the vel vectors if node is a total blank
01479       if (commitAccel == 0) 
01480         this->createAccel();
01481 
01482       // recv the committed accel
01483       if (theChannel.recvVector(dbTag3, cTag, *commitAccel) < 0) {
01484         opserr << "Node::recvSelf - failed to receive Acceleration data\n";
01485         return -4;
01486       }
01487       
01488       // set the trial values
01489       for (int i=0; i<numberDOF; i++)
01490         accel[i] = accel[i+numberDOF];  // set trial equal commited
01491     }
01492 
01493     if (data(5) == 0) {
01494       // make some room and read in the vector
01495       if (mass == 0) {
01496         mass = new Matrix(numberDOF,numberDOF);
01497         if (mass == 0) {
01498           opserr << "Node::recvData -- ran out of memory\n";
01499           return -5;
01500         }
01501       }
01502       if (theChannel.recvMatrix(dataTag, cTag, *mass) < 0) {
01503         opserr << "Node::recvSelf() - failed to receive Mass data\n";
01504         return -6;
01505       }
01506     }            
01507     
01508     if (data(12) == 0) {
01509       // create a matrix for R
01510       int noCols = data(13);
01511       if (R == 0) {
01512         R = new Matrix(numberDOF, noCols);
01513         if (R == 0) {
01514           opserr << "Node::recvData -- ran out of memory\n";
01515           return -1;
01516         }
01517       }
01518       // now recv the R matrix
01519       if (theChannel.recvMatrix(dataTag, cTag, *R) < 0) {
01520         opserr << "Node::recvSelf() - failed to receive R data\n";
01521         return res;
01522       }
01523     }
01524 
01525 
01526     if (data(6) == 0) {
01527       // create a vector for the load
01528       if (unbalLoad == 0) {
01529         unbalLoad = new Vector(numberDOF);
01530         if (unbalLoad == 0) {
01531           opserr << "Node::recvData -- ran out of memory\n";
01532           return -10;
01533         }
01534       }
01535       if (theChannel.recvVector(dbTag4, cTag, *unbalLoad) < 0) {
01536         opserr << "Node::recvSelf() - failed to receive Load data\n";
01537         return res;
01538       }
01539     }        
01540 
01541 
01542   index = -1;
01543   if (numMatrices != 0) {
01544     for (int i=0; i<numMatrices; i++)
01545       if (theMatrices[i]->noRows() == numberDOF) {
01546         index = i;
01547         i = numMatrices;
01548       }
01549   }
01550   if (index == -1) {
01551     Matrix **nextMatrices = new Matrix *[numMatrices+1];
01552     if (nextMatrices == 0) {
01553       opserr << "Element::getTheMatrix - out of memory\n";
01554       exit(-1);
01555     }
01556     for (int j=0; j<numMatrices; j++)
01557       nextMatrices[j] = theMatrices[j];
01558     Matrix *theMatrix = new Matrix(numberDOF, numberDOF);
01559     if (theMatrix == 0) {
01560       opserr << "Element::getTheMatrix - out of memory\n";
01561       exit(-1);
01562     }
01563     nextMatrices[numMatrices] = theMatrix;
01564     if (numMatrices != 0) 
01565       delete [] theMatrices;
01566     index = numMatrices;
01567     numMatrices++;
01568     theMatrices = nextMatrices;
01569   }
01570 
01571   return 0;
01572 }
01573 
01574 
01575 
01576 void
01577 Node::Print(OPS_Stream &s, int flag)
01578 {
01579   if (flag == 0) { // print out everything
01580     s << "\n Node: " << this->getTag() << endln;
01581     s << "\tCoordinates  : " << *Crd;
01582     if (commitDisp != 0)         
01583         s << "\tcommitDisps: " << *trialDisp;
01584     if (commitVel != 0)     
01585         s << "\tVelocities   : " << *trialVel;
01586     if (commitAccel != 0)         
01587         s << "\tcommitAccels: " << *trialAccel;
01588     if (unbalLoad != 0)
01589       s << "\t unbalanced Load: " << *unbalLoad;
01590     if (reaction != 0)
01591       s << "\t reaction: " << *reaction;
01592     if (mass != 0) 
01593         s << "\tMass : " << *mass;
01594     if (theEigenvectors != 0)
01595         s << "\t Eigenvectors: " << *theEigenvectors;
01596     if (theDOF_GroupPtr != 0)
01597       s << "\tID : " << theDOF_GroupPtr->getID();
01598     s << "\n"; 
01599   }
01600   else if (flag == 1) { // print out: nodeId displacements
01601     s << this->getTag() << "  " << *commitDisp;
01602   }
01603 }
01604   
01605 int
01606 Node::displaySelf(Renderer &theRenderer, int displayMode, float fact)
01607 {
01608 
01609   if (displayMode == 0)
01610     return 0;
01611 
01612   const Vector &theDisp = this->getDisp();
01613   static Vector position(3);
01614 
01615   for (int i=0; i<3; i++)
01616     if (i <Crd->Size())
01617       position(i) = (*Crd)(i) + theDisp(i)*fact;        
01618     else
01619       position(i) = 0.0;              
01620   
01621   if (displayMode == -1) { 
01622     // draw a text string containing tag
01623     static char theText[20];
01624     sprintf(theText,"%d",this->getTag());
01625     return theRenderer.drawText(position, theText, strlen(theText));
01626 
01627   } else if (displayMode > 0) {
01628     // draw a point - pixel size equals displayMode tag
01629     return theRenderer.drawPoint(position, 0.0, displayMode);
01630   }
01631 
01632 
01633   return 0;
01634 }
01635 
01636 
01637 // createDisp(), createVel() and createAccel():
01638 // private methods to create the arrays to hold the disp, vel and acceleration
01639 // values and the Vector objects for the committed and trial quantaties.
01640 
01641 int
01642 Node::createDisp(void)
01643 {
01644   // trial , committed, incr = (committed-trial)
01645   disp = new double[4*numberDOF];
01646     
01647   if (disp == 0) {
01648     opserr << "WARNING - Node::createDisp() ran out of memory for array of size " << 2*numberDOF << endln;
01649                             
01650     return -1;
01651   }
01652   for (int i=0; i<4*numberDOF; i++)
01653     disp[i] = 0.0;
01654     
01655   commitDisp = new Vector(&disp[numberDOF], numberDOF); 
01656   trialDisp = new Vector(disp, numberDOF);
01657   incrDisp = new Vector(&disp[2*numberDOF], numberDOF);
01658   incrDeltaDisp = new Vector(&disp[3*numberDOF], numberDOF);
01659   
01660   if (commitDisp == 0 || trialDisp == 0 || incrDisp == 0 || incrDeltaDisp == 0) {
01661     opserr << "WARNING - Node::createDisp() " <<
01662       "ran out of memory creating Vectors(double *,int)";
01663     return -2;
01664   }
01665     
01666   return 0;
01667 }
01668 
01669 
01670 int
01671 Node::createVel(void)
01672 {
01673     vel = new double[2*numberDOF];
01674     
01675     if (vel == 0) {
01676       opserr << "WARNING - Node::createVel() ran out of memory for array of size " << 2*numberDOF << endln;
01677       return -1;
01678     }
01679     for (int i=0; i<2*numberDOF; i++)
01680       vel[i] = 0.0;
01681     
01682     commitVel = new Vector(&vel[numberDOF], numberDOF); 
01683     trialVel = new Vector(vel, numberDOF);
01684     
01685     if (commitVel == 0 || trialVel == 0) {
01686       opserr << "WARNING - Node::createVel() %s" <<
01687         "ran out of memory creating Vectors(double *,int) \n";
01688       return -2;
01689     }
01690     
01691     return 0;
01692 }
01693 
01694 int
01695 Node::createAccel(void)
01696 {
01697     accel = new double[2*numberDOF];
01698     
01699     if (accel == 0) {
01700       opserr << "WARNING - Node::createAccel() ran out of memory for array of size " << 2*numberDOF << endln;
01701       return -1;
01702     }
01703     for (int i=0; i<2*numberDOF; i++)
01704         accel[i] = 0.0;
01705     
01706     commitAccel = new Vector(&accel[numberDOF], numberDOF);
01707     trialAccel = new Vector(accel, numberDOF);
01708     
01709     if (commitAccel == 0 || trialAccel == 0) {
01710       opserr << "WARNING - Node::createAccel() ran out of memory creating Vectors(double *,int)\n";
01711       return -2;
01712     }
01713 
01714     return 0;
01715 }
01716 
01717 
01718 // AddingSensitivity:BEGIN ///////////////////////////////////////
01719 
01720 Matrix
01721 Node::getMassSensitivity(void)
01722 {
01723         if (mass == 0) {
01724                 theMatrices[index]->Zero();
01725                 return *theMatrices[index];
01726         } 
01727         else {
01728                 Matrix massSens(mass->noRows(),mass->noCols());
01729                 if ( (parameterID == 1) || (parameterID == 2) || (parameterID == 3) ) {
01730                         massSens(parameterID-1,parameterID-1) = 1.0;
01731                 }
01732                 return massSens;
01733         }
01734 }
01735 
01736 
01737 int
01738 Node::getCrdsSensitivity(void)
01739 {
01740         if ( (parameterID == 4) || (parameterID == 5) || (parameterID == 6) ) {
01741                 return (parameterID-3);
01742         }
01743         else {
01744                 return 0;
01745         }
01746 }
01747 
01748 
01749 int
01750 Node::setParameter(const char **argv, int argc, Parameter &param)
01751 {
01752   // The following parameterID map is being used:
01753   // 1: nodal mass in direction 1       
01754   // 2: nodal mass in direction 2
01755   // 3: nodal mass in direction 3
01756   // 4: coordinate in direction 1
01757   // 5: coordinate in direction 2
01758   // 6: coordinate in direction 3
01759 
01760   if (argc < 2)
01761     return -1;
01762 
01763   if (strstr(argv[0],"mass") != 0) {
01764     int direction = atoi(argv[1]);
01765     if (direction >= 1 && direction <= 3)
01766       return param.addObject(direction, this);
01767   }
01768   else if (strstr(argv[0],"coord") != 0) {
01769     int direction = atoi(argv[1]);
01770     if (direction >= 1 && direction <= 3)
01771       return param.addObject(direction+3, this);
01772   }
01773   else
01774     opserr << "WARNING: Could not set parameter in Node. " << endln;
01775   
01776   return -1;
01777 }
01778 
01779 
01780 
01781 int
01782 Node::updateParameter(int pparameterID, Information &info)
01783 {
01784   if (pparameterID >= 1 && pparameterID <= 3)
01785     (*mass)(pparameterID-1,pparameterID-1) = info.theDouble;
01786 
01787   else if (pparameterID >= 4 && pparameterID <= 6) {
01788 
01789     if ( (*Crd)(pparameterID-4) != info.theDouble) {
01790 
01791       // Set the new coordinate value
01792       (*Crd)(pparameterID-4) = info.theDouble;
01793       
01794       // Need to "setDomain" to make the change take effect. 
01795       Domain *theDomain = this->getDomain();
01796       ElementIter &theElements = theDomain->getElements();
01797       Element *theElement;
01798       while ((theElement = theElements()) != 0) {
01799         theElement->setDomain(theDomain);
01800       }
01801     }
01802     else {
01803       // No change in nodal coordinate
01804     }
01805   }
01806   
01807   return -1;
01808 }
01809 
01810 
01811 
01812 
01813 int
01814 Node::activateParameter(int passedParameterID)
01815 {
01816         parameterID = passedParameterID;
01817 
01818         return 0;
01819 }
01820 
01821 
01822 
01823 int 
01824 Node::saveSensitivity(Vector *v,Vector *vdot,Vector *vdotdot, int gradNum, int numGrads)
01825 {
01826         // Initial declarations
01827         int i;
01828 
01829         // If the sensitivity matrices are not already created:
01830         if (dispSensitivity == 0) {
01831                 dispSensitivity = new Matrix( numberDOF, numGrads );
01832         } 
01833         if ( (vdot!=0) && (vdotdot!=0) ) {
01834                 if (velSensitivity == 0) {
01835                         velSensitivity = new Matrix( numberDOF, numGrads );
01836                 } 
01837                 if (accSensitivity == 0) {
01838                         accSensitivity = new Matrix( numberDOF, numGrads );
01839                 }
01840         }
01841 
01842         // Put GRADIENT VECTORS into COLUMNS of matrices
01843         for (i=0; i<numberDOF; i++ ) {
01844                 (*dispSensitivity)(i,gradNum-1) = (*v)(i);
01845         }
01846         if ( (vdot!=0) && (vdotdot!=0) ) {
01847                 for (i=0; i<numberDOF; i++ ) {
01848                         (*velSensitivity)(i,gradNum-1) = (*vdot)(i);
01849                 }
01850                 for (i=0; i<numberDOF; i++ ) {
01851                         (*accSensitivity)(i,gradNum-1) = (*vdotdot)(i);
01852                 }
01853         }
01854 
01855     return 0;
01856 }
01857 
01858 double 
01859 Node::getDispSensitivity(int dof, int gradNum)
01860 {
01861         double result;
01862         if (dispSensitivity != 0)
01863                 result = (*dispSensitivity)(dof-1,gradNum-1);
01864         else
01865                 result = 0.0;
01866 
01867         return result;
01868 }
01869 
01870 double 
01871 Node::getVelSensitivity(int dof, int gradNum)
01872 {
01873         if (velSensitivity != 0)
01874                 return (*velSensitivity)(dof-1,gradNum-1);
01875         else
01876                 return 0.0;
01877 }
01878 
01879 double 
01880 Node::getAccSensitivity(int dof, int gradNum)
01881 {
01882         if (accSensitivity != 0)
01883                 return (*accSensitivity)(dof-1,gradNum-1);
01884         else
01885                 return 0.0;
01886 }
01887 // AddingSensitivity:END /////////////////////////////////////////
01888 
01889 
01890 
01891 const Vector &
01892 Node::getReaction() {
01893   if (reaction == 0) {
01894     reaction = new Vector(numberDOF);
01895     if (reaction == 0) {
01896       opserr << "FATAL Node::getReaction() - out of memory\n";
01897       exit(-1);
01898     }
01899   }
01900 
01901   return *reaction;
01902 }
01903 
01904 int   
01905 Node::addReactionForce(const Vector &add, double factor){
01906 
01907   // create rection vector if have not done so already
01908   if (reaction == 0) {
01909     reaction = new Vector(numberDOF);
01910     if (reaction == 0) {
01911       opserr << "WARNING Node::addReactionForce() - out of memory\n";
01912       return -1;
01913     }
01914   }
01915 
01916   // check vector of appropraie size
01917   if (add.Size() != numberDOF) {
01918     opserr << "WARNING Node::addReactionForce() - vector not of correct size\n";
01919     return -1;
01920   }
01921 
01922   if (factor == 1.0) 
01923     *reaction += add;
01924   else if (factor == -1.0)
01925     *reaction -= add;
01926   else
01927     *reaction = add * factor;
01928 
01929   return 0;
01930 }
01931 
01932 int   
01933 Node::resetReactionForce(bool inclInertia){
01934 
01935   // create rection vector if have not done so already
01936   if (reaction == 0) {
01937     reaction = new Vector(numberDOF);
01938     if (reaction == 0) {
01939       opserr << "WARNING Node::addReactionForce() - out of memory\n";
01940       return -1;
01941     }
01942   }
01943 
01944   reaction->Zero();
01945 
01946   // add unbalance, the negative of applied forces hence the -=
01947   if (inclInertia == false) {
01948     *reaction -= this->getUnbalancedLoad();
01949   } else {
01950     *reaction -= this->getUnbalancedLoadIncInertia();
01951   }
01952 
01953   return 0;
01954 }

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