00001 // $Id: NOX_StatusTest_FiniteValue.C,v 1.8 2006/08/22 00:01:27 rppawlo Exp $ 00002 // $Source: /space/CVS/Trilinos/packages/nox/src/NOX_StatusTest_FiniteValue.C,v $ 00003 00004 //@HEADER 00005 // ************************************************************************ 00006 // 00007 // NOX: An Object-Oriented Nonlinear Solver Package 00008 // Copyright (2002) Sandia Corporation 00009 // 00010 // LOCA: Library of Continuation Algorithms Package 00011 // Copyright (2005) Sandia Corporation 00012 // 00013 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive 00014 // license for use of this work by or on behalf of the U.S. Government. 00015 // 00016 // This library is free software; you can redistribute it and/or modify 00017 // it under the terms of the GNU Lesser General Public License as 00018 // published by the Free Software Foundation; either version 2.1 of the 00019 // License, or (at your option) any later version. 00020 // 00021 // This library is distributed in the hope that it will be useful, but 00022 // WITHOUT ANY WARRANTY; without even the implied warranty of 00023 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00024 // Lesser General Public License for more details. 00025 // 00026 // You should have received a copy of the GNU Lesser General Public 00027 // License along with this library; if not, write to the Free Software 00028 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 00029 // USA 00030 // 00031 // Questions? Contact Roger Pawlowski (rppawlo@sandia.gov) or 00032 // Eric Phipps (etphipp@sandia.gov), Sandia National Laboratories. 00033 // ************************************************************************ 00034 // CVS Information 00035 // $Source: /space/CVS/Trilinos/packages/nox/src/NOX_StatusTest_FiniteValue.C,v $ 00036 // $Author: rppawlo $ 00037 // $Date: 2006/08/22 00:01:27 $ 00038 // $Revision: 1.8 $ 00039 // ************************************************************************ 00040 //@HEADER 00041 00042 #include "NOX_StatusTest_FiniteValue.H" // class definition 00043 #include "NOX_Common.H" // for string class 00044 #include "NOX_Solver_Generic.H" 00045 #include "NOX_Abstract_Group.H" 00046 00047 NOX::StatusTest::FiniteValue:: 00048 FiniteValue(VectorType v, NOX::Abstract::Vector::NormType n) : 00049 vectorType(v), 00050 vectorTypeLabel("?"), 00051 normType(n), 00052 normTypeLabel("?"), 00053 status(Unevaluated), 00054 result(-1), 00055 normValue(-1.0) 00056 { 00057 // Set the vector type label for printing 00058 if (vectorType == FVector) 00059 vectorTypeLabel = "F"; 00060 else 00061 vectorTypeLabel = "Solution"; 00062 00063 // Set the norm type label for printing 00064 if (normType == NOX::Abstract::Vector::TwoNorm) 00065 normTypeLabel = "Two-Norm"; 00066 else if (normType == NOX::Abstract::Vector::OneNorm) 00067 normTypeLabel = "One-Norm"; 00068 else 00069 normTypeLabel = "Max-Norm"; 00070 00071 } 00072 00073 NOX::StatusTest::FiniteValue::~FiniteValue() 00074 { 00075 } 00076 00077 NOX::StatusTest::StatusType NOX::StatusTest::FiniteValue:: 00078 checkStatus(const Solver::Generic& problem, 00079 NOX::StatusTest::CheckType checkType) 00080 { 00081 // Reset the check 00082 normValue = -1.0; 00083 const NOX::Abstract::Group& grp = problem.getSolutionGroup(); 00084 00085 switch (checkType) 00086 { 00087 case NOX::StatusTest::Complete: 00088 case NOX::StatusTest::Minimal: 00089 00090 00091 if (vectorType == FVector) 00092 { 00093 if (normType == NOX::Abstract::Vector::TwoNorm) 00094 normValue = grp.getNormF(); // More efficient than recomputing norm 00095 else 00096 normValue = grp.getF().norm(normType); 00097 } 00098 else 00099 normValue = grp.getX().norm(normType); 00100 00101 result = finiteNumberTest(normValue); 00102 00103 status = (result == 0) ? Unconverged : Failed; 00104 break; 00105 00106 case NOX::StatusTest::None: 00107 default: 00108 result = 1; 00109 status = Unevaluated; 00110 break; 00111 } 00112 00113 return status; 00114 } 00115 00116 NOX::StatusTest::StatusType NOX::StatusTest::FiniteValue::getStatus() const 00117 { 00118 return status; 00119 } 00120 00121 ostream& NOX::StatusTest::FiniteValue::print(ostream& stream, int indent) const 00122 { 00123 00124 00125 // Set the correct label for the check result 00126 string label = "Unknown"; 00127 if (result == 0) 00128 label = "Finite"; 00129 else if (result == -1) 00130 label = "NaN"; 00131 else if (result == -2) 00132 label = "Infinite"; 00133 00134 for (int j = 0; j < indent; j ++) 00135 stream << ' '; 00136 stream << status; 00137 stream << "Finite Number Check (" << normTypeLabel; 00138 stream << " " << vectorTypeLabel; 00139 stream << ") = "; 00140 stream << label; 00141 //stream << " (" << normValue << ")"; 00142 stream << endl; 00143 00144 return stream; 00145 } 00146 00147 int NOX::StatusTest::FiniteValue::finiteNumberTest(double x) const 00148 { 00149 if (NOX_isnan(x)) 00150 return -1; 00151 00152 if (NOX_isinf(x)) 00153 return -2; 00154 00155 return 0; 00156 } 00157 00158 bool NOX::StatusTest::FiniteValue::NOX_isnan(double x) const 00159 { 00160 #ifdef HAVE_NAN_SUPPORT 00161 if (isnan(x)) 00162 #else 00163 if (x != x) 00164 #endif 00165 return true; 00166 00167 return false; 00168 } 00169 00170 bool NOX::StatusTest::FiniteValue::NOX_isinf(double x) const 00171 { 00172 #ifdef HAVE_INF_SUPPORT 00173 if (isinf(x)) 00174 #else 00175 // Use IEEE 754 definition: Inf * 0 = NaN 00176 double z = 0.0 * x; 00177 if (NOX_isnan(z)) 00178 #endif 00179 return true; 00180 00181 return false; 00182 }