NewtonLineSearch.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.5 $
00022 // $Date: 2005/11/29 22:42:42 $
00023 // $Source: /usr/local/cvs/OpenSees/SRC/analysis/algorithm/equiSolnAlgo/NewtonLineSearch.cpp,v $
00024 
00025 // Written: fmk 
00026 // Created: 11/96 
00027 // Modified: Ed "C++" Love 10/00 to perform the line search
00028 //
00029 // Description: This file contains the implementation for NewtonLineSearch. 
00030 // 
00031 // What: "@(#)NewtonLineSearch.h, revA"
00032 
00033 #include <NewtonLineSearch.h>
00034 #include <AnalysisModel.h>
00035 #include <StaticAnalysis.h>
00036 #include <IncrementalIntegrator.h>
00037 #include <LinearSOE.h>
00038 #include <Channel.h>
00039 #include <FEM_ObjectBroker.h>
00040 #include <ConvergenceTest.h>
00041 #include <ID.h>
00042 
00043 
00044 //Null Constructor
00045 NewtonLineSearch::NewtonLineSearch( )
00046 :EquiSolnAlgo(EquiALGORITHM_TAGS_NewtonLineSearch),
00047  theTest(0), theLineSearch(0)
00048 {   
00049 }
00050 
00051 
00052 //Constructor 
00053 NewtonLineSearch::NewtonLineSearch( ConvergenceTest &theT, 
00054                                    LineSearch *theSearch) 
00055 :EquiSolnAlgo(EquiALGORITHM_TAGS_NewtonLineSearch),
00056  theTest(&theT), theLineSearch(theSearch)
00057 {
00058 
00059 }
00060 
00061 
00062 // Destructor
00063 NewtonLineSearch::~NewtonLineSearch()
00064 {
00065 
00066 }
00067 
00068 int
00069 NewtonLineSearch::setConvergenceTest(ConvergenceTest *newTest)
00070 {
00071     theTest = newTest;
00072     return 0;
00073 }
00074 
00075 
00076 int 
00077 NewtonLineSearch::solveCurrentStep(void)
00078 {
00079     // set up some pointers and check they are valid
00080     // NOTE this could be taken away if we set Ptrs as protecetd in superclass
00081     AnalysisModel   *theAnaModel = this->getAnalysisModelPtr();
00082     IncrementalIntegrator *theIntegrator = this->getIncrementalIntegratorPtr();
00083     LinearSOE  *theSOE = this->getLinearSOEptr();
00084 
00085     if ((theAnaModel == 0) || (theIntegrator == 0) || (theSOE == 0)
00086         || (theTest == 0)){
00087         opserr << "WARNING NewtonLineSearch::solveCurrentStep() - setLinks() has";
00088         opserr << " not been called - or no ConvergenceTest has been set\n";
00089         return -5;
00090     }   
00091 
00092     theLineSearch->newStep(*theSOE);
00093 
00094     // set itself as the ConvergenceTest objects EquiSolnAlgo
00095     theTest->setEquiSolnAlgo(*this);
00096     if (theTest->start() < 0) {
00097       opserr << "NewtonLineSearch::solveCurrentStep() -";
00098       opserr << "the ConvergenceTest object failed in start()\n";
00099       return -3;
00100     }
00101 
00102     if (theIntegrator->formUnbalance() < 0) {
00103       opserr << "WARNING NewtonLineSearch::solveCurrentStep() -";
00104       opserr << "the Integrator failed in formUnbalance()\n";   
00105       return -2;
00106     }       
00107 
00108     int result = -1;
00109     do {
00110 
00111         //residual at this iteration before next solve 
00112         const Vector &Resid0 = theSOE->getB() ;
00113 
00114         
00115         //form the tangent
00116         if (theIntegrator->formTangent() < 0){
00117             opserr << "WARNING NewtonLineSearch::solveCurrentStep() -";
00118             opserr << "the Integrator failed in formTangent()\n";
00119             return -1;
00120         }                   
00121         
00122         //solve 
00123         if (theSOE->solve() < 0) {
00124             opserr << "WARNING NewtonLineSearch::solveCurrentStep() -";
00125             opserr << "the LinearSysOfEqn failed in solve()\n"; 
00126             return -3;
00127         }           
00128 
00129 
00130         //line search direction 
00131         const Vector &dx0 = theSOE->getX() ;
00132 
00133         //intial value of s
00134         double s0 = - (dx0 ^ Resid0) ; 
00135 
00136         if (theIntegrator->update(theSOE->getX()) < 0) {
00137             opserr << "WARNING NewtonLineSearch::solveCurrentStep() -";
00138             opserr << "the Integrator failed in update()\n";    
00139             return -4;
00140         }               
00141 
00142         if (theIntegrator->formUnbalance() < 0) {
00143             opserr << "WARNING NewtonLineSearch::solveCurrentStep() -";
00144             opserr << "the Integrator failed in formUnbalance()\n";     
00145             return -2;
00146         }       
00147 
00148         //new residual 
00149         const Vector &Resid = theSOE->getB() ;
00150 
00151         //new value of s 
00152         double s = - ( dx0 ^ Resid ) ;
00153 
00154         if (theLineSearch != 0)
00155           theLineSearch->search(s0, s, *theSOE, *theIntegrator);
00156         
00157         this->record(0);
00158 
00159         result = theTest->test();
00160 
00161     } while (result == -1);
00162 
00163     if (result == -2) {
00164       opserr << "NewtonLineSearch::solveCurrentStep() -";
00165       opserr << "the ConvergenceTest object failed in test()\n";
00166       return -3;
00167     }
00168 
00169     // note - if postive result we are returning what the convergence test returned
00170     // which should be the number of iterations
00171     return result;
00172 }
00173 
00174 ConvergenceTest *
00175 NewtonLineSearch::getConvergenceTest(void)
00176 {
00177   return theTest;
00178 }
00179 
00180 int
00181 NewtonLineSearch::sendSelf(int cTag, Channel &theChannel)
00182 {
00183   return -1;
00184 }
00185 
00186 int
00187 NewtonLineSearch::recvSelf(int cTag, 
00188                         Channel &theChannel, 
00189                         FEM_ObjectBroker &theBroker)
00190 {
00191   return -1;
00192 }
00193 
00194 
00195 void
00196 NewtonLineSearch::Print(OPS_Stream &s, int flag)
00197 {
00198   if (flag == 0) 
00199     s << "NewtonLineSearch\n";
00200 
00201   if (theLineSearch != 0)
00202     theLineSearch->Print(s, flag);
00203 }
00204 
00205 
00206 
00207 
00208 
00209 
00210 
00211 
00212 

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