AlgorithmA.cpp

Go to the documentation of this file.
00001 #include "AlgorithmA.hpp"
00002 #include "Teuchos_VerboseObjectParameterListHelpers.hpp"
00003 #include "Teuchos_StandardParameterEntryValidators.hpp"
00004 
00005 
00006 // This is a typical function that would be present in Trilinos right now what
00007 // does not know about FancyOStream and does not derive from VerboseObject.
00008 // However, because of the magic of FancyOStream, this output will be indented
00009 // correctly!
00010 void someDumbFunction( std::ostream &out, const std::string &indentSpacer )
00011 {
00012   out << "\nEntering someDumbFunction(...)\n";
00013   {
00014     out << std::endl << indentSpacer << "I am \"dumb\" code that knows nothing of FancyOStream and does indenting manually! ...\n";
00015   }
00016   out << "\nLeaving someDumbFunction(...)\n";
00017   // Note that this output will be indented correctly even through it knows nothing of FancyOStream
00018 }
00019 
00020 // This is a function who's interface was written before there was a
00021 // FancyOStream and therefore is written in terms of std::ostream.  However,
00022 // in this case the implementation has been modifed to use FancyOStream as
00023 // shown.
00024 void someLessDumbFunction( std::ostream &out_arg )
00025 {
00026   using Teuchos::OSTab;
00027   // Get a FancyOStream from out_arg or create a new one ...
00028   Teuchos::RCP<Teuchos::FancyOStream>
00029     out = Teuchos::getFancyOStream(Teuchos::rcp(&out_arg,false));
00030   // Do our tab indent and our name.
00031   OSTab tab(out,1,"LDUMBALGO");
00032   *out << "\nEntering someLessDumbFunction(...)\n";
00033   {
00034     Teuchos::OSTab(out_arg).o()
00035       << std::endl << "I am less \"dumb\" code that knows about FancyOStream but my interface does not support it directly! ...\n";
00036     *Teuchos::tab(out)
00037       << std::endl << "Another print from this less \"dumb\" code ...\n";
00038   }
00039   *out << "\nLeaving someLessDumbFunction(...)\n";
00040 }
00041 
00042 
00043 namespace {
00044 
00045 const std::string AlgoType_name = "Algo Type";
00046 const std::string AlgoType_default = "Bob";
00047 
00048 const std::string AlgoTol_name = "Algo Tol";
00049 const double AlgoTol_default = 1e-5;
00050 
00051 } // namespace
00052 
00053 
00054 const std::string AlgorithmA::toString( AlgorithmA::EAlgoType algoType )
00055 {
00056   switch(algoType) {
00057     case ALGO_BOB: return "Bob";
00058     case ALGO_JOHN: return "John";
00059     case ALGO_HARRY: return "Harry";
00060     default: TEST_FOR_EXCEPT("Should never get here!");
00061   }
00062   return ""; // never be called!
00063 }
00064 
00065 
00066 AlgorithmA::AlgorithmA()
00067   : algoType_(ALGO_BOB), algoTol_(AlgoTol_default)
00068 {
00069   this->setLinePrefix("ALGO_A"); // I tell me who I am for line prefix outputting
00070 }
00071 
00072 
00073 void AlgorithmA::setParameterList(
00074   Teuchos::RCP<Teuchos::ParameterList> const& paramList
00075   )
00076 {
00077   TEST_FOR_EXCEPT(is_null(paramList));
00078   // Validate and set the parameter defaults.  Here, the parameters are
00079   // validated and the state of *this is not changed unless the parameter
00080   // validation succeeds.  Also, any validators that are defined for various
00081   // parameters are passed along so that they can be used in extracting
00082   // values!
00083   paramList->validateParametersAndSetDefaults(*this->getValidParameters(),0);
00084   paramList_ = paramList;
00085   // Get the enum value for the algorithm type. Here, the actual type stored
00086   // for the algorithm type in the parameter list is an std::string but this
00087   // helper function does all the work of extracting the validator set in
00088   // getValidParameters() and set on *paramList_ through the
00089   // validateParametersAndSetDefaults(...) function above!
00090   algoType_ = Teuchos::getIntegralValue<EAlgoType>(*paramList_,AlgoType_name);
00091   // Get the tolerance for the algorithm.  Here, the actual type of the
00092   // parameter stored on input could be many different types.  Here, I can
00093   // just assume that it is a double since it would have been converted to a
00094   // double above in validateParametersAndSetDefaults(...).
00095   algoTol_ = Teuchos::getParameter<double>(*paramList_,AlgoTol_name);
00096   // Read the sublist for verbosity settings.
00097   Teuchos::readVerboseObjectSublist(&*paramList_,this);
00098 #ifdef TEUCHOS_DEBUG
00099   paramList_->validateParameters(*this->getValidParameters());
00100 #endif
00101 }
00102 
00103 
00104 Teuchos::RCP<Teuchos::ParameterList>
00105 AlgorithmA::getNonconstParameterList()
00106 {
00107   return paramList_;
00108 }
00109 
00110 
00111 Teuchos::RCP<Teuchos::ParameterList>
00112 AlgorithmA::unsetParameterList()
00113 {
00114   Teuchos::RCP<Teuchos::ParameterList> paramList = paramList_;
00115   paramList_ = Teuchos::null;
00116   return paramList;
00117 }
00118 
00119 
00120 Teuchos::RCP<const Teuchos::ParameterList>
00121 AlgorithmA::getParameterList() const
00122 {
00123   return paramList_;
00124 }
00125 
00126 
00127 Teuchos::RCP<const Teuchos::ParameterList>
00128 AlgorithmA::getValidParameters() const
00129 {
00130   using Teuchos::RCP; using Teuchos::ParameterList;
00131   using Teuchos::setStringToIntegralParameter;
00132   using Teuchos::tuple;
00133   static RCP<const ParameterList> validParams;
00134   if (is_null(validParams)) {
00135     RCP<ParameterList>
00136       pl = Teuchos::rcp(new ParameterList("AlgorithmA"));
00137     setStringToIntegralParameter<EAlgoType>(
00138       AlgoType_name, AlgoType_default,
00139       "The algorithm type to use",
00140       tuple<std::string>("Bob", "John", "Harry"),
00141       tuple<EAlgoType>(ALGO_BOB, ALGO_JOHN, ALGO_HARRY),
00142       &*pl
00143       );
00144     Teuchos::setDoubleParameter(
00145       AlgoTol_name, AlgoTol_default,
00146       "The tolerance for the algorithm.",
00147       &*pl
00148       );
00149     Teuchos::setupVerboseObjectSublist(&*pl);
00150     validParams = pl;
00151   }
00152   return validParams;
00153 }
00154 
00155 
00156 void AlgorithmA::doAlgorithm()
00157 {
00158   using Teuchos::OSTab;
00159   // Get the verbosity that we are going to use
00160   Teuchos::EVerbosityLevel verbLevel = this->getVerbLevel();
00161   // Here I grab the stream that I will use for outputting.  It is a good
00162   // idea to grab the RCP to this object just to be safe.
00163   Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
00164   // Here I set my line prefix and a single indent.  The convention will
00165   // be that a called function will set its own indent.  This convention makes
00166   // the most sense.
00167   OSTab tab = this->getOSTab(); // This sets the line prefix and adds one tab
00168   if(out.get() && includesVerbLevel(verbLevel,Teuchos::VERB_LOW,true))
00169     *out << "\nEntering AlgorithmA::doAlgorithm() with verbLevel="<<Teuchos::toString(verbLevel)<<"\n";
00170   {
00171     // Here I use a simple macro for the typical case of one tab indent to
00172     // save typing.  The idea is that this should be as easy to write as
00173     // OSTab tab; but is more general.
00174     TEUCHOS_OSTAB;
00175     if(out.get() && includesVerbLevel(verbLevel,Teuchos::VERB_LOW,true))
00176       *out
00177         << "\nI am \"smart\" code that knows about FancyOStream and OSTab ...\n"
00178         << "\nDoing algorithm of type \""<<toString(algoType_)<<"\""
00179         << "\nUsing tolerance of " << algoTol_ << "\n";
00180     {
00181       // Here I temporaraly turn off tabbing so that I can print an imporant warning message.
00182       OSTab tab2 = this->getOSTab(OSTab::DISABLE_TABBING);
00183       if(out.get() && includesVerbLevel(verbLevel,Teuchos::VERB_LOW,true))
00184         *out << "\n***\n*** Warning, I am doing something very dangerous so watch out!!!\n***\n";
00185     }
00186     if(out.get() && includesVerbLevel(verbLevel,Teuchos::VERB_LOW,true))
00187       *out << "\nHere I am doing some more stuff and printing with indenting turned back on!\n";
00188     {
00189       // Here I am going to be calling a dumb piece of code that does not
00190       // know about the FancyOStream system and will not use tabs or
00191       // anything like that.  There is a lot of code in Trilinos that
00192       // falls in this category.  The first thing I do is manually indent
00193       // the stream one tab and set a line prefix for the dumb code since
00194       // it may not do this itself.
00195       OSTab tab2 = this->getOSTab(1,"DUMBALGO");
00196       // Now a Pass in the updated FancyOStream object, which is properly
00197       // indented now, through the std::ostream interface.  I also pass in
00198       // the std::string that is being used for creating tabs.  The output from
00199       // this function will be indented correctly without the dumb code
00200       // knowing it!
00201       someDumbFunction(*out,out->getTabIndentStr());
00202     }
00203     // Here I am calling a less dumb piece of code who's interface does
00204     // not support FancyOStream but the implementation does.  Note that
00205     // this function also follows the convention of doing an initial
00206     // indent.
00207     someLessDumbFunction(*out);
00208   }
00209   if(out.get() && includesVerbLevel(verbLevel,Teuchos::VERB_LOW,true))
00210     *out << "\nLeaving AlgorithmA::doAlgorithm()\n";
00211 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Generated on Wed Apr 13 09:57:27 2011 for Teuchos Package Browser (Single Doxygen Collection) by  doxygen 1.6.3