|
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 // This library is free software; you can redistribute it and/or modify 00012 // it under the terms of the GNU Lesser General Public License as 00013 // published by the Free Software Foundation; either version 2.1 of the 00014 // License, or (at your option) any later version. 00015 // 00016 // This library is distributed in the hope that it will be useful, but 00017 // WITHOUT ANY WARRANTY; without even the implied warranty of 00018 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00019 // Lesser General Public License for more details. 00020 // 00021 // You should have received a copy of the GNU Lesser General Public 00022 // License along with this library; if not, write to the Free Software 00023 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 00024 // USA 00025 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 00026 // 00027 // *********************************************************************** 00028 // @HEADER 00029 */ 00030 00031 #include "AlgorithmA.hpp" 00032 #include "Teuchos_VerboseObjectParameterListHelpers.hpp" 00033 #include "Teuchos_StandardParameterEntryValidators.hpp" 00034 00035 00036 // This is a typical function that would be present in Trilinos right now what 00037 // does not know about FancyOStream and does not derive from VerboseObject. 00038 // However, because of the magic of FancyOStream, this output will be indented 00039 // correctly! 00040 void someDumbFunction( std::ostream &out, const std::string &indentSpacer ) 00041 { 00042 out << "\nEntering someDumbFunction(...)\n"; 00043 { 00044 out << std::endl << indentSpacer << "I am \"dumb\" code that knows nothing of FancyOStream and does indenting manually! ...\n"; 00045 } 00046 out << "\nLeaving someDumbFunction(...)\n"; 00047 // Note that this output will be indented correctly even through it knows nothing of FancyOStream 00048 } 00049 00050 // This is a function who's interface was written before there was a 00051 // FancyOStream and therefore is written in terms of std::ostream. However, 00052 // in this case the implementation has been modifed to use FancyOStream as 00053 // shown. 00054 void someLessDumbFunction( std::ostream &out_arg ) 00055 { 00056 using Teuchos::OSTab; 00057 // Get a FancyOStream from out_arg or create a new one ... 00058 Teuchos::RCP<Teuchos::FancyOStream> 00059 out = Teuchos::getFancyOStream(Teuchos::rcp(&out_arg,false)); 00060 // Do our tab indent and our name. 00061 OSTab tab(out,1,"LDUMBALGO"); 00062 *out << "\nEntering someLessDumbFunction(...)\n"; 00063 { 00064 Teuchos::OSTab(out_arg).o() 00065 << std::endl << "I am less \"dumb\" code that knows about FancyOStream but my interface does not support it directly! ...\n"; 00066 *Teuchos::tab(out) 00067 << std::endl << "Another print from this less \"dumb\" code ...\n"; 00068 } 00069 *out << "\nLeaving someLessDumbFunction(...)\n"; 00070 } 00071 00072 00073 namespace { 00074 00075 const std::string AlgoType_name = "Algo Type"; 00076 const std::string AlgoType_default = "Bob"; 00077 00078 const std::string AlgoTol_name = "Algo Tol"; 00079 const double AlgoTol_default = 1e-5; 00080 00081 } // namespace 00082 00083 00084 const std::string AlgorithmA::toString( AlgorithmA::EAlgoType algoType ) 00085 { 00086 switch(algoType) { 00087 case ALGO_BOB: return "Bob"; 00088 case ALGO_JOHN: return "John"; 00089 case ALGO_HARRY: return "Harry"; 00090 default: TEST_FOR_EXCEPT("Should never get here!"); 00091 } 00092 return ""; // never be called! 00093 } 00094 00095 00096 AlgorithmA::AlgorithmA() 00097 : algoType_(ALGO_BOB), algoTol_(AlgoTol_default) 00098 { 00099 this->setLinePrefix("ALGO_A"); // I tell me who I am for line prefix outputting 00100 } 00101 00102 00103 void AlgorithmA::setParameterList( 00104 Teuchos::RCP<Teuchos::ParameterList> const& paramList 00105 ) 00106 { 00107 TEST_FOR_EXCEPT(is_null(paramList)); 00108 // Validate and set the parameter defaults. Here, the parameters are 00109 // validated and the state of *this is not changed unless the parameter 00110 // validation succeeds. Also, any validators that are defined for various 00111 // parameters are passed along so that they can be used in extracting 00112 // values! 00113 paramList->validateParametersAndSetDefaults(*this->getValidParameters(),0); 00114 paramList_ = paramList; 00115 // Get the enum value for the algorithm type. Here, the actual type stored 00116 // for the algorithm type in the parameter list is an std::string but this 00117 // helper function does all the work of extracting the validator set in 00118 // getValidParameters() and set on *paramList_ through the 00119 // validateParametersAndSetDefaults(...) function above! 00120 algoType_ = Teuchos::getIntegralValue<EAlgoType>(*paramList_,AlgoType_name); 00121 // Get the tolerance for the algorithm. Here, the actual type of the 00122 // parameter stored on input could be many different types. Here, I can 00123 // just assume that it is a double since it would have been converted to a 00124 // double above in validateParametersAndSetDefaults(...). 00125 algoTol_ = Teuchos::getParameter<double>(*paramList_,AlgoTol_name); 00126 // Read the sublist for verbosity settings. 00127 Teuchos::readVerboseObjectSublist(&*paramList_,this); 00128 #ifdef TEUCHOS_DEBUG 00129 paramList_->validateParameters(*this->getValidParameters()); 00130 #endif 00131 } 00132 00133 00134 Teuchos::RCP<Teuchos::ParameterList> 00135 AlgorithmA::getNonconstParameterList() 00136 { 00137 return paramList_; 00138 } 00139 00140 00141 Teuchos::RCP<Teuchos::ParameterList> 00142 AlgorithmA::unsetParameterList() 00143 { 00144 Teuchos::RCP<Teuchos::ParameterList> paramList = paramList_; 00145 paramList_ = Teuchos::null; 00146 return paramList; 00147 } 00148 00149 00150 Teuchos::RCP<const Teuchos::ParameterList> 00151 AlgorithmA::getParameterList() const 00152 { 00153 return paramList_; 00154 } 00155 00156 00157 Teuchos::RCP<const Teuchos::ParameterList> 00158 AlgorithmA::getValidParameters() const 00159 { 00160 using Teuchos::RCP; using Teuchos::ParameterList; 00161 using Teuchos::setStringToIntegralParameter; 00162 using Teuchos::tuple; 00163 static RCP<const ParameterList> validParams; 00164 if (is_null(validParams)) { 00165 RCP<ParameterList> 00166 pl = Teuchos::rcp(new ParameterList("AlgorithmA")); 00167 setStringToIntegralParameter<EAlgoType>( 00168 AlgoType_name, AlgoType_default, 00169 "The algorithm type to use", 00170 tuple<std::string>("Bob", "John", "Harry"), 00171 tuple<EAlgoType>(ALGO_BOB, ALGO_JOHN, ALGO_HARRY), 00172 &*pl 00173 ); 00174 Teuchos::setDoubleParameter( 00175 AlgoTol_name, AlgoTol_default, 00176 "The tolerance for the algorithm.", 00177 &*pl 00178 ); 00179 Teuchos::setupVerboseObjectSublist(&*pl); 00180 validParams = pl; 00181 } 00182 return validParams; 00183 } 00184 00185 00186 void AlgorithmA::doAlgorithm() 00187 { 00188 using Teuchos::OSTab; 00189 // Get the verbosity that we are going to use 00190 Teuchos::EVerbosityLevel verbLevel = this->getVerbLevel(); 00191 // Here I grab the stream that I will use for outputting. It is a good 00192 // idea to grab the RCP to this object just to be safe. 00193 Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream(); 00194 // Here I set my line prefix and a single indent. The convention will 00195 // be that a called function will set its own indent. This convention makes 00196 // the most sense. 00197 OSTab tab = this->getOSTab(); // This sets the line prefix and adds one tab 00198 if(out.get() && includesVerbLevel(verbLevel,Teuchos::VERB_LOW,true)) 00199 *out << "\nEntering AlgorithmA::doAlgorithm() with verbLevel="<<Teuchos::toString(verbLevel)<<"\n"; 00200 { 00201 // Here I use a simple macro for the typical case of one tab indent to 00202 // save typing. The idea is that this should be as easy to write as 00203 // OSTab tab; but is more general. 00204 TEUCHOS_OSTAB; 00205 if(out.get() && includesVerbLevel(verbLevel,Teuchos::VERB_LOW,true)) 00206 *out 00207 << "\nI am \"smart\" code that knows about FancyOStream and OSTab ...\n" 00208 << "\nDoing algorithm of type \""<<toString(algoType_)<<"\"" 00209 << "\nUsing tolerance of " << algoTol_ << "\n"; 00210 { 00211 // Here I temporaraly turn off tabbing so that I can print an imporant warning message. 00212 OSTab tab2 = this->getOSTab(OSTab::DISABLE_TABBING); 00213 if(out.get() && includesVerbLevel(verbLevel,Teuchos::VERB_LOW,true)) 00214 *out << "\n***\n*** Warning, I am doing something very dangerous so watch out!!!\n***\n"; 00215 } 00216 if(out.get() && includesVerbLevel(verbLevel,Teuchos::VERB_LOW,true)) 00217 *out << "\nHere I am doing some more stuff and printing with indenting turned back on!\n"; 00218 { 00219 // Here I am going to be calling a dumb piece of code that does not 00220 // know about the FancyOStream system and will not use tabs or 00221 // anything like that. There is a lot of code in Trilinos that 00222 // falls in this category. The first thing I do is manually indent 00223 // the stream one tab and set a line prefix for the dumb code since 00224 // it may not do this itself. 00225 OSTab tab2 = this->getOSTab(1,"DUMBALGO"); 00226 // Now a Pass in the updated FancyOStream object, which is properly 00227 // indented now, through the std::ostream interface. I also pass in 00228 // the std::string that is being used for creating tabs. The output from 00229 // this function will be indented correctly without the dumb code 00230 // knowing it! 00231 someDumbFunction(*out,out->getTabIndentStr()); 00232 } 00233 // Here I am calling a less dumb piece of code who's interface does 00234 // not support FancyOStream but the implementation does. Note that 00235 // this function also follows the convention of doing an initial 00236 // indent. 00237 someLessDumbFunction(*out); 00238 } 00239 if(out.get() && includesVerbLevel(verbLevel,Teuchos::VERB_LOW,true)) 00240 *out << "\nLeaving AlgorithmA::doAlgorithm()\n"; 00241 }
1.7.4