|
Teuchos Package Browser (Single Doxygen Collection)
Version of the Day
|
00001 /* 00002 // @HEADER 00003 // *********************************************************************** 00004 // 00005 // Teuchos: Common Tools Package 00006 // Copyright (2004) Sandia Corporation 00007 // 00008 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive 00009 // license for use of this work by or on behalf of the U.S. Government. 00010 // 00011 // Redistribution and use in source and binary forms, with or without 00012 // modification, are permitted provided that the following conditions are 00013 // met: 00014 // 00015 // 1. Redistributions of source code must retain the above copyright 00016 // notice, this list of conditions and the following disclaimer. 00017 // 00018 // 2. Redistributions in binary form must reproduce the above copyright 00019 // notice, this list of conditions and the following disclaimer in the 00020 // documentation and/or other materials provided with the distribution. 00021 // 00022 // 3. Neither the name of the Corporation nor the names of the 00023 // contributors may be used to endorse or promote products derived from 00024 // this software without specific prior written permission. 00025 // 00026 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY 00027 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00028 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 00029 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE 00030 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00031 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00032 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00033 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00034 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00035 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00036 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00037 // 00038 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 00039 // 00040 // *********************************************************************** 00041 // @HEADER 00042 */ 00043 00044 #include "AlgorithmA.hpp" 00045 #include "Teuchos_VerboseObjectParameterListHelpers.hpp" 00046 #include "Teuchos_StandardParameterEntryValidators.hpp" 00047 00048 00049 // This is a typical function that would be present in Trilinos right now what 00050 // does not know about FancyOStream and does not derive from VerboseObject. 00051 // However, because of the magic of FancyOStream, this output will be indented 00052 // correctly! 00053 void someDumbFunction( std::ostream &out, const std::string &indentSpacer ) 00054 { 00055 out << "\nEntering someDumbFunction(...)\n"; 00056 { 00057 out << std::endl << indentSpacer << "I am \"dumb\" code that knows nothing of FancyOStream and does indenting manually! ...\n"; 00058 } 00059 out << "\nLeaving someDumbFunction(...)\n"; 00060 // Note that this output will be indented correctly even through it knows nothing of FancyOStream 00061 } 00062 00063 // This is a function who's interface was written before there was a 00064 // FancyOStream and therefore is written in terms of std::ostream. However, 00065 // in this case the implementation has been modifed to use FancyOStream as 00066 // shown. 00067 void someLessDumbFunction( std::ostream &out_arg ) 00068 { 00069 using Teuchos::OSTab; 00070 // Get a FancyOStream from out_arg or create a new one ... 00071 Teuchos::RCP<Teuchos::FancyOStream> 00072 out = Teuchos::getFancyOStream(Teuchos::rcp(&out_arg,false)); 00073 // Do our tab indent and our name. 00074 OSTab tab(out,1,"LDUMBALGO"); 00075 *out << "\nEntering someLessDumbFunction(...)\n"; 00076 { 00077 Teuchos::OSTab(out_arg).o() 00078 << std::endl << "I am less \"dumb\" code that knows about FancyOStream but my interface does not support it directly! ...\n"; 00079 *Teuchos::tab(out) 00080 << std::endl << "Another print from this less \"dumb\" code ...\n"; 00081 } 00082 *out << "\nLeaving someLessDumbFunction(...)\n"; 00083 } 00084 00085 00086 namespace { 00087 00088 const std::string AlgoType_name = "Algo Type"; 00089 const std::string AlgoType_default = "Bob"; 00090 00091 const std::string AlgoTol_name = "Algo Tol"; 00092 const double AlgoTol_default = 1e-5; 00093 00094 } // namespace 00095 00096 00097 const std::string AlgorithmA::toString( AlgorithmA::EAlgoType algoType ) 00098 { 00099 switch(algoType) { 00100 case ALGO_BOB: return "Bob"; 00101 case ALGO_JOHN: return "John"; 00102 case ALGO_HARRY: return "Harry"; 00103 default: TEUCHOS_TEST_FOR_EXCEPT("Should never get here!"); 00104 } 00105 return ""; // never be called! 00106 } 00107 00108 00109 AlgorithmA::AlgorithmA() 00110 : algoType_(ALGO_BOB), algoTol_(AlgoTol_default) 00111 { 00112 this->setLinePrefix("ALGO_A"); // I tell me who I am for line prefix outputting 00113 } 00114 00115 00116 void AlgorithmA::setParameterList( 00117 Teuchos::RCP<Teuchos::ParameterList> const& paramList 00118 ) 00119 { 00120 TEUCHOS_TEST_FOR_EXCEPT(is_null(paramList)); 00121 // Validate and set the parameter defaults. Here, the parameters are 00122 // validated and the state of *this is not changed unless the parameter 00123 // validation succeeds. Also, any validators that are defined for various 00124 // parameters are passed along so that they can be used in extracting 00125 // values! 00126 paramList->validateParametersAndSetDefaults(*this->getValidParameters(),0); 00127 paramList_ = paramList; 00128 // Get the enum value for the algorithm type. Here, the actual type stored 00129 // for the algorithm type in the parameter list is an std::string but this 00130 // helper function does all the work of extracting the validator set in 00131 // getValidParameters() and set on *paramList_ through the 00132 // validateParametersAndSetDefaults(...) function above! 00133 algoType_ = Teuchos::getIntegralValue<EAlgoType>(*paramList_,AlgoType_name); 00134 // Get the tolerance for the algorithm. Here, the actual type of the 00135 // parameter stored on input could be many different types. Here, I can 00136 // just assume that it is a double since it would have been converted to a 00137 // double above in validateParametersAndSetDefaults(...). 00138 algoTol_ = Teuchos::getParameter<double>(*paramList_,AlgoTol_name); 00139 // Read the sublist for verbosity settings. 00140 Teuchos::readVerboseObjectSublist(&*paramList_,this); 00141 #ifdef TEUCHOS_DEBUG 00142 paramList_->validateParameters(*this->getValidParameters()); 00143 #endif 00144 } 00145 00146 00147 Teuchos::RCP<Teuchos::ParameterList> 00148 AlgorithmA::getNonconstParameterList() 00149 { 00150 return paramList_; 00151 } 00152 00153 00154 Teuchos::RCP<Teuchos::ParameterList> 00155 AlgorithmA::unsetParameterList() 00156 { 00157 Teuchos::RCP<Teuchos::ParameterList> paramList = paramList_; 00158 paramList_ = Teuchos::null; 00159 return paramList; 00160 } 00161 00162 00163 Teuchos::RCP<const Teuchos::ParameterList> 00164 AlgorithmA::getParameterList() const 00165 { 00166 return paramList_; 00167 } 00168 00169 00170 Teuchos::RCP<const Teuchos::ParameterList> 00171 AlgorithmA::getValidParameters() const 00172 { 00173 using Teuchos::RCP; using Teuchos::ParameterList; 00174 using Teuchos::setStringToIntegralParameter; 00175 using Teuchos::tuple; 00176 static RCP<const ParameterList> validParams; 00177 if (is_null(validParams)) { 00178 RCP<ParameterList> 00179 pl = Teuchos::rcp(new ParameterList("AlgorithmA")); 00180 setStringToIntegralParameter<EAlgoType>( 00181 AlgoType_name, AlgoType_default, 00182 "The algorithm type to use", 00183 tuple<std::string>("Bob", "John", "Harry"), 00184 tuple<EAlgoType>(ALGO_BOB, ALGO_JOHN, ALGO_HARRY), 00185 &*pl 00186 ); 00187 Teuchos::setDoubleParameter( 00188 AlgoTol_name, AlgoTol_default, 00189 "The tolerance for the algorithm.", 00190 &*pl 00191 ); 00192 Teuchos::setupVerboseObjectSublist(&*pl); 00193 validParams = pl; 00194 } 00195 return validParams; 00196 } 00197 00198 00199 void AlgorithmA::doAlgorithm() 00200 { 00201 using Teuchos::OSTab; 00202 // Get the verbosity that we are going to use 00203 Teuchos::EVerbosityLevel verbLevel = this->getVerbLevel(); 00204 // Here I grab the stream that I will use for outputting. It is a good 00205 // idea to grab the RCP to this object just to be safe. 00206 Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream(); 00207 // Here I set my line prefix and a single indent. The convention will 00208 // be that a called function will set its own indent. This convention makes 00209 // the most sense. 00210 OSTab tab = this->getOSTab(); // This sets the line prefix and adds one tab 00211 if(out.get() && includesVerbLevel(verbLevel,Teuchos::VERB_LOW,true)) 00212 *out << "\nEntering AlgorithmA::doAlgorithm() with verbLevel="<<Teuchos::toString(verbLevel)<<"\n"; 00213 { 00214 // Here I use a simple macro for the typical case of one tab indent to 00215 // save typing. The idea is that this should be as easy to write as 00216 // OSTab tab; but is more general. 00217 TEUCHOS_OSTAB; 00218 if(out.get() && includesVerbLevel(verbLevel,Teuchos::VERB_LOW,true)) 00219 *out 00220 << "\nI am \"smart\" code that knows about FancyOStream and OSTab ...\n" 00221 << "\nDoing algorithm of type \""<<toString(algoType_)<<"\"" 00222 << "\nUsing tolerance of " << algoTol_ << "\n"; 00223 { 00224 // Here I temporaraly turn off tabbing so that I can print an imporant warning message. 00225 OSTab tab2 = this->getOSTab(OSTab::DISABLE_TABBING); 00226 if(out.get() && includesVerbLevel(verbLevel,Teuchos::VERB_LOW,true)) 00227 *out << "\n***\n*** Warning, I am doing something very dangerous so watch out!!!\n***\n"; 00228 } 00229 if(out.get() && includesVerbLevel(verbLevel,Teuchos::VERB_LOW,true)) 00230 *out << "\nHere I am doing some more stuff and printing with indenting turned back on!\n"; 00231 { 00232 // Here I am going to be calling a dumb piece of code that does not 00233 // know about the FancyOStream system and will not use tabs or 00234 // anything like that. There is a lot of code in Trilinos that 00235 // falls in this category. The first thing I do is manually indent 00236 // the stream one tab and set a line prefix for the dumb code since 00237 // it may not do this itself. 00238 OSTab tab2 = this->getOSTab(1,"DUMBALGO"); 00239 // Now a Pass in the updated FancyOStream object, which is properly 00240 // indented now, through the std::ostream interface. I also pass in 00241 // the std::string that is being used for creating tabs. The output from 00242 // this function will be indented correctly without the dumb code 00243 // knowing it! 00244 someDumbFunction(*out,out->getTabIndentStr()); 00245 } 00246 // Here I am calling a less dumb piece of code who's interface does 00247 // not support FancyOStream but the implementation does. Note that 00248 // this function also follows the convention of doing an initial 00249 // indent. 00250 someLessDumbFunction(*out); 00251 } 00252 if(out.get() && includesVerbLevel(verbLevel,Teuchos::VERB_LOW,true)) 00253 *out << "\nLeaving AlgorithmA::doAlgorithm()\n"; 00254 }
1.7.6.1