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

CTestEnergyIncr.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/06/14 05:26:47 $
00023 // $Source: /usr/local/cvs/OpenSees/SRC/convergenceTest/CTestEnergyIncr.cpp,v $
00024                                                                         
00025                                                                         
00026 // File: ~/convergenceTest/CTestEnergyIncr.C
00027 //
00028 // Written: fmk 
00029 // Date: 09/98
00030 // Revised:
00031 //
00032 // Purpose: This file contains the class implementation for CTestEnergyIncr.
00033 // A CTestEnergyIncr object tests for convergence using the energy increment,
00034 // which is 0.5 times the absolute value of the product of the rhs and 
00035 // the solution vector of the LinearSOE.
00036 
00037 #include <CTestEnergyIncr.h>
00038 #include <Vector.h>
00039 #include <Channel.h>
00040 #include <EquiSolnAlgo.h>
00041 #include <LinearSOE.h>
00042 
00043 CTestEnergyIncr::CTestEnergyIncr()      
00044 :ConvergenceTest(CONVERGENCE_TEST_CTestEnergyIncr),
00045  theSOE(0), tol(0), maxNumIter(0), currentIter(0), printFlag(0),
00046  norms(1)
00047 {
00048     
00049 }
00050 
00051 CTestEnergyIncr::CTestEnergyIncr(double theTol, int maxIter, int printIt)
00052 :ConvergenceTest(CONVERGENCE_TEST_CTestEnergyIncr),
00053  theSOE(0), tol(theTol), maxNumIter(maxIter), currentIter(0),printFlag(printIt),
00054  norms(maxNumIter)
00055 {
00056 
00057 }
00058 
00059 CTestEnergyIncr::~CTestEnergyIncr()
00060 {
00061     
00062 }
00063 
00064 ConvergenceTest*
00065 CTestEnergyIncr::getCopy( int iterations )
00066 {
00067   CTestEnergyIncr *theCopy ;
00068   theCopy = new CTestEnergyIncr( this->tol, iterations, this->printFlag ) ;
00069 
00070   theCopy->theSOE = this->theSOE ;
00071 
00072   return theCopy ;
00073 }
00074 
00075 void
00076 CTestEnergyIncr::setTolerance(double newTol)
00077 {
00078     tol = newTol;
00079 }
00080 
00081 int
00082 CTestEnergyIncr::setEquiSolnAlgo(EquiSolnAlgo &theAlgo)
00083 {
00084     theSOE = theAlgo.getLinearSOEptr();
00085     if (theSOE == 0) {
00086  cerr << "WARNING: CTestEnergyIncr::setEquiSolnAlgo - no SOE\n"; 
00087  return -1;
00088     }
00089     else
00090  return 0;
00091 }
00092 
00093     
00094 int
00095 CTestEnergyIncr::test(void)
00096 {
00097   // check to ensure the SOE has been set - this should not happen if the 
00098   // return from start() is checked
00099   if (theSOE == 0)
00100     return -2;
00101 
00102   // check to ensure the algo does invoke start() - this is needed otherwise
00103   // may never get convergence later on in analysis!
00104   if (currentIter == 0) {
00105     cerr << "WARNING: CTestEnergyIncr::test() - start() was never invoked.\n"; 
00106     return -2;
00107   }
00108 
00109 
00110   // determine the energy & save value in norms vector
00111   const Vector &b = theSOE->getB();
00112   const Vector &x = theSOE->getX();    
00113   double product = x ^ b;
00114   if (product < 0.0)
00115     product *= -0.5;
00116   else
00117     product *= 0.5;
00118 
00119   if (currentIter <= maxNumIter) 
00120     norms(currentIter-1) = product;
00121 
00122   // print the data if required
00123   if (printFlag == 1) {
00124     cerr << "CTestEnergyIncr::test() - iteration: " << currentIter;
00125     cerr << " current Product: " << product << " (max: " << tol << ")\n";
00126   }
00127   if (printFlag == 4) {
00128     cerr << "CTestEnergyIncr::test() - iteration: " << currentIter;
00129     cerr << " current Product: " << product << " (max: " << tol << ")\n";
00130     cerr << " Norm deltaX: " << x.Norm() << "  Norm deltaR: " << b.Norm() << endl;
00131     cerr << "deltaX: " << x << " deltaR: " << b;
00132   }
00133 
00134   //
00135   // check if the algorithm converged
00136   //
00137 
00138   // if converged - print & return ok
00139   if (product <= tol) {
00140 
00141     // do some printing first
00142     if (printFlag != 0) {
00143       if (printFlag == 1) 
00144  cerr << endl;
00145       else if (printFlag == 2) {
00146  cerr << "CTestEnergyIncr::test() - iteration: " << currentIter;
00147  cerr << " last incr: " << product << " (max permissable: " << tol << ")\n";
00148       }
00149     }
00150 
00151     // return the number of times test has been called - SUCCESSFULL
00152     return currentIter;
00153   }
00154 
00155   // algo failed to converged after specified number of iterations - but RETURN OK
00156   else if (printFlag == 5 && currentIter >= maxNumIter) {
00157     cerr << "WARNING: CTestEnergyIncr::test() - failed to converge but goin on - ";
00158     cerr << " current Product: " << product << " (max: " << tol << ")\n";
00159     cerr << " Norm deltaX: " << x.Norm() << "  Norm deltaR: " << b.Norm() << endl;
00160     return currentIter;
00161   }
00162 
00163   // algo failed to converged after specified number of iterations - return FAILURE -2
00164   else if (currentIter >= maxNumIter) { // >= in case algorithm does not check
00165     cerr << "WARNING: CTestEnergyIncr::test() - failed to converge \n";
00166     cerr << "after: " << currentIter << " iterations\n"; 
00167     currentIter++;    
00168     return -2;
00169   } 
00170 
00171   // algo not yet converged - increment counter and return -1
00172   else {
00173       currentIter++;    
00174       return -1;
00175     }
00176 }
00177 
00178 int
00179 CTestEnergyIncr::start(void)
00180 {
00181     if (theSOE == 0) {
00182  cerr << "WARNING: CTestEnergyIncr::test() - no SOE returning true\n";
00183  return -1;
00184     }
00185 
00186     currentIter = 1;
00187     norms.Zero();
00188     return 0;
00189 }
00190 
00191 
00192 int 
00193 CTestEnergyIncr::getNumTests(void)
00194 {
00195   return currentIter;
00196 }
00197 
00198 int 
00199 CTestEnergyIncr::getMaxNumTests(void)
00200 {
00201   return maxNumIter;
00202 }
00203 
00204 double 
00205 CTestEnergyIncr::getRatioNumToMax(void)
00206 {
00207     double div = maxNumIter;
00208     return currentIter/div;
00209 }
00210 
00211 
00212 const Vector &
00213 CTestEnergyIncr::getNorms(void) 
00214 {
00215   return norms;
00216 }
00217 
00218 
00219 int 
00220 CTestEnergyIncr::sendSelf(int cTag, Channel &theChannel)
00221 {
00222   int res = 0;
00223   Vector x(2);
00224   x(0) = tol;
00225   x(1) = maxNumIter;
00226 
00227   
00228   res = theChannel.sendVector(this->getDbTag(), cTag, x);
00229   if (res < 0) 
00230     cerr << "CTestEnergyIncr::sendSelf() - failed to send data\n";
00231     
00232   return res;
00233 }
00234 
00235 int 
00236 CTestEnergyIncr::recvSelf(int cTag, Channel &theChannel, 
00237      FEM_ObjectBroker &theBroker)
00238 {
00239   int res = 0;
00240   Vector x(2);
00241   res = theChannel.recvVector(this->getDbTag(), cTag, x);    
00242 
00243   if (res < 0) {
00244       cerr << "CTestEnergyIncr::sendSelf() - failed to send data\n";
00245       tol = 1.0e-8;
00246       maxNumIter = 25;
00247   }
00248   else {
00249       tol = x(0);
00250       maxNumIter = x(1);
00251       norms.resize(maxNumIter);
00252   }
00253     
00254   return res;
00255 }
00256 
00257 
00258 
00259 
00260 
00261 
Copyright Contact Us