Teuchos Package Browser (Single Doxygen Collection) Version of the Day
AlgorithmA.cpp
Go to the documentation of this file.
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: 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   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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines