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

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