PeriodicNewton.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.3 $
00022 // $Date: 2005/11/29 22:42:42 $
00023 // $Source: /usr/local/cvs/OpenSees/SRC/analysis/algorithm/equiSolnAlgo/PeriodicNewton.cpp,v $
00024 
00025 // Written: MHS
00026 // Created: Oct 2002
00027 //
00028 // Description: This file contains the class definition for 
00029 // PeriodicNewton. PeriodicNewton is a class which uses the
00030 // Newton-Raphson solution algorihm
00031 // to solve the equations. No member functions are declared as virtual as 
00032 // it is not expected that this class will be subclassed.
00033 
00034 #include <PeriodicNewton.h>
00035 #include <AnalysisModel.h>
00036 #include <StaticAnalysis.h>
00037 #include <IncrementalIntegrator.h>
00038 #include <LinearSOE.h>
00039 #include <ID.h>
00040 #include <Channel.h>
00041 #include <FEM_ObjectBroker.h>
00042 #include <ConvergenceTest.h>
00043 
00044 // Constructor
00045 PeriodicNewton::PeriodicNewton(int theTangentToUse, int mc)
00046 :EquiSolnAlgo(EquiALGORITHM_TAGS_PeriodicNewton),
00047  theTest(0), tangent(theTangentToUse), maxCount(mc)
00048 {
00049   
00050 }
00051 
00052 
00053 PeriodicNewton::PeriodicNewton(ConvergenceTest &theT, int theTangentToUse, int mc)
00054 :EquiSolnAlgo(EquiALGORITHM_TAGS_PeriodicNewton),
00055  theTest(&theT), tangent(theTangentToUse), maxCount(mc)
00056 {
00057 
00058 }
00059 
00060 // Destructor
00061 PeriodicNewton::~PeriodicNewton()
00062 {
00063 
00064 }
00065 
00066 int
00067 PeriodicNewton::setConvergenceTest(ConvergenceTest *newTest)
00068 {
00069     theTest = newTest;
00070     return 0;
00071 }
00072 
00073 int 
00074 PeriodicNewton::solveCurrentStep(void)
00075 {
00076     // set up some pointers and check they are valid
00077     // NOTE this could be taken away if we set Ptrs as protecetd in superclass
00078     AnalysisModel       *theAnalysisModel = this->getAnalysisModelPtr();
00079     IncrementalIntegrator *theIncIntegratorr = this->getIncrementalIntegratorPtr();
00080     LinearSOE           *theSOE = this->getLinearSOEptr();
00081 
00082     if ((theAnalysisModel == 0) || (theIncIntegratorr == 0) || (theSOE == 0)
00083         || (theTest == 0)){
00084         opserr << "WARNING PeriodicNewton::solveCurrentStep() - setLinks() has";
00085         opserr << " not been called - or no ConvergenceTest has been set\n";
00086         return -5;
00087     }   
00088 
00089     // we form the tangent
00090     
00091     if (theIncIntegratorr->formUnbalance() < 0) {
00092         opserr << "WARNING PeriodicNewton::solveCurrentStep() -";
00093         opserr << "the Integrator failed in formUnbalance()\n"; 
00094         return -2;
00095     }   
00096 
00097     if (theIncIntegratorr->formTangent(tangent) < 0){
00098         opserr << "WARNING PeriodicNewton::solveCurrentStep() -";
00099         opserr << "the Integrator failed in formTangent()\n";
00100         return -1;
00101     }               
00102 
00103     // set itself as the ConvergenceTest objects EquiSolnAlgo
00104     theTest->setEquiSolnAlgo(*this);
00105     if (theTest->start() < 0) {
00106       opserr << "PeriodicNewton::solveCurrentStep() -";
00107       opserr << "the ConvergenceTest object failed in start()\n";
00108       return -3;
00109     }
00110 
00111     // repeat until convergence is obtained or reach max num iterations
00112     int result = -1;
00113     int count = 0;
00114         int iter = 0;
00115     do {
00116         if (theSOE->solve() < 0) {
00117             opserr << "WARNING PeriodicNewton::solveCurrentStep() -";
00118             opserr << "the LinearSysOfEqn failed in solve()\n"; 
00119             return -3;
00120         }           
00121 
00122         if (theIncIntegratorr->update(theSOE->getX()) < 0) {
00123             opserr << "WARNING PeriodicNewton::solveCurrentStep() -";
00124             opserr << "the Integrator failed in update()\n";    
00125             return -4;
00126         }               
00127 
00128         if (theIncIntegratorr->formUnbalance() < 0) {
00129             opserr << "WARNING PeriodicNewton::solveCurrentStep() -";
00130             opserr << "the Integrator failed in formUnbalance()\n";     
00131             return -2;
00132         }       
00133 
00134         this->record(count++);
00135         result = theTest->test();
00136         
00137         iter++;
00138         if (iter > maxCount) {
00139                 if (theIncIntegratorr->formTangent(tangent) < 0){
00140                 opserr << "WARNING PeriodicNewton::solveCurrentStep() -";
00141                 opserr << "the Integrator failed in formTangent()\n";
00142                 return -1;
00143                 }
00144                 iter = 0;
00145         }
00146 
00147     } while (result == -1);
00148 
00149     if (result == -2) {
00150       opserr << "PeriodicNewton::solveCurrentStep() -";
00151       opserr << "the ConvergenceTest object failed in test()\n";
00152       return -3;
00153     }
00154 
00155     return result;
00156 }
00157 
00158 ConvergenceTest *
00159 PeriodicNewton::getConvergenceTest(void)
00160 {
00161   return theTest;
00162 }
00163 
00164 int
00165 PeriodicNewton::sendSelf(int cTag, Channel &theChannel)
00166 {
00167   int result = 0;
00168   int dataTag = this->getDbTag();
00169   static ID data(3);
00170   data(0) = theTest->getClassTag();
00171   data(1) = theTest->getDbTag();
00172   data(2) = maxCount;
00173 
00174   result = theChannel.sendID(dataTag, cTag, data);
00175   if (result != 0) {
00176     opserr << "PeriodicNewton::sendSelf() - failed to send ID\n";
00177     return result;
00178   }
00179 
00180   result = theTest->sendSelf(cTag, theChannel);
00181   if (result != 0) {
00182     opserr << "PeriodicNewton::sendSelf() - failed to send CTest object\n";
00183     return result;
00184   }
00185   
00186   return 0;
00187 }
00188 
00189 int
00190 PeriodicNewton::recvSelf(int cTag, 
00191                         Channel &theChannel, 
00192                         FEM_ObjectBroker &theBroker)
00193 {
00194     static ID data(3);
00195     int result;
00196     int dataTag = this->getDbTag();
00197 
00198     result = theChannel.recvID(dataTag, cTag, data);    
00199     if (result != 0) {
00200       opserr << "PeriodicNewton::recvSelf() - failed to receive ID\n";
00201       return result;
00202     }
00203     int ctType = data(0);
00204     int ctDb = data(1);
00205     maxCount = data(2);
00206 
00207     theTest = theBroker.getNewConvergenceTest(ctType);
00208     theTest->setDbTag(ctDb);
00209     result = theTest->recvSelf(cTag, theChannel, theBroker);
00210     if (result != 0) {
00211       opserr << "PeriodicNewton::recvSelf() - failed to recv CTest object\n";
00212       return result;
00213     }
00214     
00215     return 0;
00216 }
00217 
00218 void
00219 PeriodicNewton::Print(OPS_Stream &s, int flag)
00220 {
00221     if (flag == 0) {
00222         s << "PeriodicNewton" << endln;
00223         s << "Max count: " << maxCount << endln;
00224     }
00225 }

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