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 // 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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines