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

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