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

DisplacementControl.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.4 $
00022 // $Date: 2001/05/30 01:42:35 $
00023 // $Source: /usr/local/cvs/OpenSees/SRC/analysis/integrator/DisplacementControl.cpp,v $
00024                                                                         
00025                                                                         
00026 // File: ~/analysis/integrator/DisplacementControl.C
00027 // 
00028 // Written: fmk 
00029 // Created: 07/98
00030 // Revision: A
00031 //
00032 // Description: This file contains the class definition for DisplacementControl.
00033 // DisplacementControl is an algorithmic class for perfroming a static analysis
00034 // using the arc length scheme, that is within a load step the follwing
00035 // constraint is enforced: dU^TdU + alpha^2*dLambda^2 = DisplacementControl^2
00036 // where dU is change in nodal displacements for step, dLambda is
00037 // change in applied load and DisplacementControl is a control parameter.
00038 //
00039 // What: "@(#) DisplacementControl.C, revA"
00040 
00041 
00042 #include <DisplacementControl.h>
00043 #include <AnalysisModel.h>
00044 #include <LinearSOE.h>
00045 #include <Vector.h>
00046 #include <Channel.h>
00047 #include <iostream.h>
00048 #include <math.h>
00049 #include <Domain.h>
00050 #include <Node.h>
00051 #include <DOF_Group.h>
00052 #include <ID.h>
00053 
00054 DisplacementControl::DisplacementControl(int node, int dof, 
00055       double increment, 
00056       Domain *domain,
00057       int numIncr,
00058       double min, double max) 
00059 :StaticIntegrator(INTEGRATOR_TAGS_DisplacementControl),
00060  theNode(node), theDof(dof), theIncrement(increment), theDomain(domain),
00061  theDofID(0),
00062  deltaUhat(0), deltaUbar(0), deltaU(0), deltaUstep(0), 
00063  phat(0), deltaLambdaStep(0.0), currentLambda(0.0),
00064  specNumIncrStep(numIncr), numIncrLastStep(numIncr),
00065  minIncrement(min), maxIncrement(max)
00066 {
00067   // to avoid divide-by-zero error on first update() ensure numIncr != 0
00068   if (numIncr == 0) {
00069     cerr << "WARNING DisplacementControl::DisplacementControl() -";
00070     cerr << " numIncr set to 0, 1 assumed\n";
00071     specNumIncrStep = 1.0;
00072     numIncrLastStep = 1.0;
00073   }
00074 }
00075 
00076 DisplacementControl::~DisplacementControl()
00077 {
00078     // delete any vector object created
00079     if (deltaUhat != 0)
00080  delete deltaUhat;
00081     if (deltaU != 0)
00082  delete deltaU;
00083     if (deltaUstep != 0)
00084  delete deltaUstep;
00085     if (phat != 0)
00086  delete phat;
00087 }
00088 
00089 int
00090 DisplacementControl::newStep(void)
00091 {
00092 
00093 
00094     // get pointers to AnalysisModel and LinearSOE
00095     AnalysisModel *theModel = this->getAnalysisModelPtr();
00096     LinearSOE *theLinSOE = this->getLinearSOEPtr();    
00097     if (theModel == 0 || theLinSOE == 0) {
00098  cerr << "WARNING DisplacementControl::newStep() ";
00099  cerr << "No AnalysisModel or LinearSOE has been set\n";
00100  return -1;
00101     }
00102 
00103 
00104     // determine increment for this iteration
00105     double factor = specNumIncrStep/numIncrLastStep;
00106     theIncrement *=factor;
00107 
00108     if (theIncrement < minIncrement)
00109       theIncrement = minIncrement;
00110     else if (theIncrement > maxIncrement)
00111       theIncrement = maxIncrement;
00112 
00113 
00114     // get the current load factor
00115     currentLambda = theModel->getCurrentDomainTime();
00116 
00117     // determine dUhat
00118     this->formTangent();
00119     theLinSOE->setB(*phat);
00120 
00121     theLinSOE->solve();
00122     (*deltaUhat) = theLinSOE->getX();
00123     Vector &dUhat = *deltaUhat;
00124 
00125     double dUahat = dUhat(theDofID);
00126     
00127     // determine delta lambda(1) == dlambda    
00128     double dLambda = theIncrement/dUahat;
00129 
00130     deltaLambdaStep = dLambda;
00131     currentLambda += dLambda;
00132  //   cerr << "DisplacementControl: " << dUahat  << " " << theDofID << endl;
00133  //   cerr << "DisplacementControl::newStep() : " << deltaLambdaStep << endl;
00134     // determine delta U(1) == dU
00135     (*deltaU) = dUhat;
00136     (*deltaU) *= dLambda;
00137     (*deltaUstep) = (*deltaU);
00138 
00139     // update model with delta lambda and delta U
00140     theModel->incrDisp(*deltaU);    
00141     theModel->applyLoadDomain(currentLambda);    
00142     theModel->updateDomain();
00143 
00144     numIncrLastStep = 0;
00145 
00146     return 0;
00147 }
00148 
00149 int
00150 DisplacementControl::update(const Vector &dU)
00151 {
00152     AnalysisModel *theModel = this->getAnalysisModelPtr();
00153     LinearSOE *theLinSOE = this->getLinearSOEPtr();    
00154     if (theModel == 0 || theLinSOE == 0) {
00155  cerr << "WARNING DisplacementControl::update() ";
00156  cerr << "No AnalysisModel or LinearSOE has been set\n";
00157  return -1;
00158     }
00159 
00160     (*deltaUbar) = dU; // have to do this as the SOE is gonna change
00161     double dUabar = (*deltaUbar)(theDofID);
00162     
00163     // determine dUhat    
00164     theLinSOE->setB(*phat);
00165     theLinSOE->solve();
00166     (*deltaUhat) = theLinSOE->getX();    
00167 
00168     double dUahat = (*deltaUhat)(theDofID);
00169     
00170     // determine delta lambda(1) == dlambda    
00171     double dLambda = -dUabar/dUahat;
00172     
00173     // determine delta U(i)
00174     (*deltaU) = (*deltaUbar);    
00175     deltaU->addVector(1.0, *deltaUhat,dLambda);
00176     
00177     // update dU and dlambda
00178     (*deltaUstep) += *deltaU;
00179     deltaLambdaStep += dLambda;
00180     currentLambda += dLambda;
00181 
00182     // update the model
00183     theModel->incrDisp(*deltaU);    
00184     theModel->applyLoadDomain(currentLambda);    
00185     theModel->updateDomain();
00186     
00187     // set the X soln in linearSOE to be deltaU for convergence Test
00188     for (int i=0; i<deltaU->Size(); i++)
00189  theLinSOE->setX(i, (*deltaU)(i));
00190 
00191     numIncrLastStep++;
00192 
00193     return 0;
00194 }
00195 
00196 
00197 
00198 int 
00199 DisplacementControl::domainChanged(void)
00200 {
00201     // we first create the Vectors needed
00202     AnalysisModel *theModel = this->getAnalysisModelPtr();
00203     LinearSOE *theLinSOE = this->getLinearSOEPtr();    
00204     if (theModel == 0 || theLinSOE == 0) {
00205  cerr << "WARNING DisplacementControl::update() ";
00206  cerr << "No AnalysisModel or LinearSOE has been set\n";
00207  return -1;
00208     }    
00209     int size = theModel->getNumEqn(); // ask model in case N+1 space
00210 
00211     if (deltaUhat == 0 || deltaUhat->Size() != size) { // create new Vector
00212  if (deltaUhat != 0)
00213      delete deltaUhat;   // delete the old
00214  deltaUhat = new Vector(size);
00215  if (deltaUhat == 0 || deltaUhat->Size() != size) { // check got it
00216      cerr << "FATAL DisplacementControl::domainChanged() - ran out of memory for";
00217      cerr << " deltaUhat Vector of size " << size << endl;
00218      exit(-1);
00219  }
00220     }
00221 
00222     if (deltaUbar == 0 || deltaUbar->Size() != size) { // create new Vector
00223  if (deltaUbar != 0)
00224      delete deltaUbar;   // delete the old
00225  deltaUbar = new Vector(size);
00226  if (deltaUbar == 0 || deltaUbar->Size() != size) { // check got it
00227      cerr << "FATAL DisplacementControl::domainChanged() - ran out of memory for";
00228      cerr << " deltaUbar Vector of size " << size << endl;
00229      exit(-1);
00230  }
00231     }
00232     
00233     if (deltaU == 0 || deltaU->Size() != size) { // create new Vector
00234  if (deltaU != 0)
00235      delete deltaU;   // delete the old
00236  deltaU = new Vector(size);
00237  if (deltaU == 0 || deltaU->Size() != size) { // check got it
00238      cerr << "FATAL DisplacementControl::domainChanged() - ran out of memory for";
00239      cerr << " deltaU Vector of size " << size << endl;
00240      exit(-1);
00241  }
00242     }
00243 
00244     if (deltaUstep == 0 || deltaUstep->Size() != size) { 
00245  if (deltaUstep != 0)
00246      delete deltaUstep;  
00247  deltaUstep = new Vector(size);
00248  if (deltaUstep == 0 || deltaUstep->Size() != size) { 
00249      cerr << "FATAL DisplacementControl::domainChanged() - ran out of memory for";
00250      cerr << " deltaUstep Vector of size " << size << endl;
00251      exit(-1);
00252  }
00253     }
00254 
00255     if (phat == 0 || phat->Size() != size) { 
00256  if (phat != 0)
00257      delete phat;  
00258  phat = new Vector(size);
00259  if (phat == 0 || phat->Size() != size) { 
00260      cerr << "FATAL DisplacementControl::domainChanged() - ran out of memory for";
00261      cerr << " phat Vector of size " << size << endl;
00262      exit(-1);
00263  }
00264     }    
00265 
00266     // now we have to determine phat
00267     // do this by incrementing lambda by 1, applying load
00268     // and getting phat from unbalance.
00269     currentLambda = theModel->getCurrentDomainTime();
00270     currentLambda += 1.0;
00271     theModel->applyLoadDomain(currentLambda);    
00272     this->formUnbalance(); // NOTE: this assumes unbalance at last was 0
00273     (*phat) = theLinSOE->getB();
00274     currentLambda -= 1.0;
00275     theModel->setCurrentDomainTime(currentLambda);    
00276 
00277 
00278     // check there is a reference load
00279     int haveLoad = 0;
00280     for (int i=0; i<size; i++)
00281       if ( (*phat)(i) != 0.0 ) {
00282  haveLoad = 1;
00283  i = size;
00284       }
00285 
00286     if (haveLoad == 0) {
00287       cerr << "WARNING DisplacementControl::domainChanged() - zero reference load";
00288       return -1;
00289     }
00290 
00291     // lastly we determine the id of the nodal dof
00292     // EXTRA CODE TO DO SOME ERROR CHECKING REQUIRED
00293     
00294     Node *theNodePtr = theDomain->getNode(theNode);
00295     DOF_Group *theGroup = theNodePtr->getDOF_GroupPtr();
00296     const ID &theID = theGroup->getID();
00297     theDofID = theID(theDof);
00298     
00299     return 0;
00300 }
00301 
00302 int
00303 DisplacementControl::sendSelf(int cTag,
00304       Channel &theChannel)
00305 {
00306     // TO FINISH
00307   return 0;
00308 }
00309 
00310 
00311 int
00312 DisplacementControl::recvSelf(int cTag,
00313       Channel &theChannel, FEM_ObjectBroker &theBroker)
00314 {
00315     // TO FINISH
00316   return 0;
00317 }
00318 
00319 void
00320 DisplacementControl::Print(ostream &s, int flag)
00321 {
00322     // TO FINISH    
00323 }
Copyright Contact Us