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

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