Teuchos Package Browser (Single Doxygen Collection) Version of the Day
test/ParameterList/cxx_main.cpp
Go to the documentation of this file.
00001 // @HEADER
00002 // ***********************************************************************
00003 //
00004 //                    Teuchos: Common Tools Package
00005 //                 Copyright (2004) Sandia Corporation
00006 //
00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00008 // license for use of this work by or on behalf of the U.S. Government.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
00038 //
00039 // ***********************************************************************
00040 // @HEADER
00041 
00042 #include "Teuchos_ParameterList.hpp"
00043 #include "Teuchos_GlobalMPISession.hpp"
00044 #include "Teuchos_CommandLineProcessor.hpp"
00045 #include "Teuchos_getConst.hpp"
00046 #include "Teuchos_Version.hpp"
00047 #include "Teuchos_StandardCatchMacros.hpp"
00048 #include "Teuchos_FancyOStream.hpp"
00049 #include "Teuchos_ArrayRCP.hpp"
00050 #include "Teuchos_StandardParameterEntryValidators.hpp"
00051 
00052 #ifdef HAVE_TEUCHOS_EXTENDED
00053 #include "Teuchos_XMLParameterListHelpers.hpp"
00054 #endif
00055 
00056 #ifdef HAVE_MPI
00057 #include "mpi.h"
00058 #endif
00059 
00060 using Teuchos::CommandLineProcessor;
00061 using Teuchos::ParameterList;
00062 using Teuchos::getParameter;
00063 typedef ParameterList::PrintOptions PLPrintOptions;
00064 using Teuchos::ParameterEntry;
00065 using Teuchos::OSTab;
00066 using Teuchos::rcp;
00067 using Teuchos::inoutArg;
00068 
00069 void print_break() { std::cout << "---------------------------------------------------" << std::endl; }
00070 double Plus ( double a, double b ) { return a+b; }
00071 
00072 int main( int argc, char *argv[] )
00073 {
00074 
00075   using std::cout;
00076   using std::endl;
00077 
00078   bool verbose = true;
00079   int FailedTests = 0;
00080   bool result;
00081 
00082   Teuchos::GlobalMPISession mpiSession(&argc,&argv);
00083   const int procRank = Teuchos::GlobalMPISession::getRank();
00084 
00085   bool success = true;
00086 
00087   try {
00088 
00089   // Read options from the command line. 
00090   CommandLineProcessor  clp(false); // Don't throw exceptions
00091   clp.setOption( "verbose", "quiet", &verbose, "Set if output is printed or not." );
00092   CommandLineProcessor::EParseCommandLineReturn parse_return = clp.parse(argc,argv);
00093   if( parse_return != CommandLineProcessor::PARSE_SUCCESSFUL ) {
00094     cout << "Processor "<< procRank <<", parse_return "<< parse_return << std::endl;
00095     cout << "End Result: TEST FAILED" << std::endl;
00096     return parse_return;
00097   }
00098 
00099   // Only print on 0 processor
00100   if (procRank != 0 && verbose)
00101     verbose = false;
00102 
00103   if (verbose)
00104     cout << Teuchos::Teuchos_Version() << std::endl << std::endl;
00105 
00106   //-----------------------------------------------------------
00107   // Create Main Parameter List / Sublist Structure
00108   //-----------------------------------------------------------
00109 
00110   ParameterList PL_Main("PL_Main");
00111   const std::string Direction_Doc = "This sublist controls how direction is computed.";
00112   ParameterList& PL_Direction = PL_Main.sublist("Direction",false,Direction_Doc);
00113   ParameterList& PL_Newton = PL_Direction.sublist("Newton");
00114   ParameterList& PL_LinSol = PL_Newton.sublist("Linear Solver");
00115   ParameterList& PL_LineSearch = PL_Main.sublist("Line Search");
00116 
00117   //-----------------------------------------------------------
00118   // Check Parameter List Structure
00119   //-----------------------------------------------------------
00120   if (verbose) {
00121     print_break();
00122     cout << "Empty Parameter List Structure" << std::endl;
00123     print_break();
00124     cout<<PL_Main<< std::endl;
00125   }
00126   if (verbose) cout << "Is 'Direction' recognized as a sublist of 'Main' ... ";
00127   if ( PL_Main.isSublist( "Direction" ) ) {  
00128     if (verbose) cout << "yes"<< std::endl;
00129   } else {
00130     if (verbose) cout << "no"<< std::endl;
00131     FailedTests++;        
00132   }
00133   if (verbose) cout << "Is 'Newton' recognized as a sublist of 'Direction' ... ";
00134   if ( PL_Direction.isSublist( "Newton" ) ) {  
00135     if (verbose) cout << "yes"<< std::endl;
00136   } else {
00137     if (verbose) cout << "no"<< std::endl;
00138     FailedTests++;        
00139   }
00140   if (verbose) cout << "Is 'Linear Solver' recognized as a sublist of 'Newton' ... ";
00141   if ( PL_Newton.isSublist( "Linear Solver" ) ) {  
00142     if (verbose) cout << "yes"<< std::endl;
00143   } else {
00144     if (verbose) cout << "no"<< std::endl;
00145     FailedTests++;        
00146   }
00147   if (verbose) cout << "Is 'Line Search' recognized as a sublist of 'Main' ... ";
00148   if ( PL_Main.isSublist( "Line Search" ) ) {  
00149     if (verbose) cout << "yes"<< std::endl;
00150   } else {
00151     if (verbose) cout << "no"<< std::endl;
00152     FailedTests++;        
00153   }
00154 
00155   if (verbose) cout << "Is subist documentation std::string maintained ...\n";
00156   {
00157     Teuchos::OSTab tab(cout);
00158     const Teuchos::ParameterEntry
00159       *paramEntry = PL_Main.getEntryPtr("Direction");
00160     TEUCHOS_TEST_FOR_EXCEPT(0==paramEntry);
00161     const std::string extracted_Direction_Doc = paramEntry->docString();
00162     if (verbose) tab.o() << "Expected doc std::string = \"" << Direction_Doc << "\"\n";
00163     if (verbose) tab.o() << "Extracted doc std::string = \"" << extracted_Direction_Doc << "\"\n";
00164     if (extracted_Direction_Doc == Direction_Doc) {
00165       if (verbose) tab.o() << "passed!  They match :-)\n";
00166     }
00167     else {
00168       if (verbose) tab.o() << "failed!  They do not match :-("<< std::endl;
00169       FailedTests++;        
00170     }
00171   }
00172   
00173 
00174   //-----------------------------------------------------------
00175   // Fill in Direction Sublist
00176   //-----------------------------------------------------------
00177 
00178   double tol = 0.0;
00179   bool RBNS = false;
00180   PL_Direction.get("Method", "Newton");
00181   PL_LinSol.set("Tol",1e-5);
00182   tol = PL_LinSol.get("Tolerance",1e-10);
00183   RBNS = PL_Newton.get("Rescue Bad Newton Solve", true );
00184 
00185   //-----------------------------------------------------------
00186   // Print out Direction Sublist
00187   //-----------------------------------------------------------
00188   if (verbose) {
00189     print_break();
00190     cout << "Direction Parameter List" << std::endl;
00191     print_break();
00192     PL_Direction.print(cout);
00193   }
00194   if (verbose) cout << "Is 'Newton' recognized as a parameter of 'Direction' ... ";
00195   if ( PL_Direction.isParameter( "Newton" ) ) {  
00196     if (verbose) cout << "yes"<< std::endl;
00197   } else {
00198     if (verbose) cout << "no"<< std::endl;
00199     FailedTests++;        
00200   }
00201   if (verbose) cout << "Is 'Tolerance' recognized as a parameter of 'Newton' ... ";
00202   if ( PL_Newton.isParameter( "Tolerance" ) ) {  
00203     if (verbose) cout << "yes (should be no)"<< std::endl;
00204     FailedTests++;
00205   } else {
00206     if (verbose) cout << "no (as expected)"<< std::endl;
00207   }
00208   if (verbose) cout << "Is 'Tolerance' recognized as a parameter of 'Linear Solver' ... ";
00209   if ( PL_LinSol.isParameter( "Tolerance" ) ) {  
00210     if (verbose) cout << "yes"<< std::endl;
00211   } else {
00212     if (verbose) cout << "no"<< std::endl;
00213     FailedTests++;        
00214   }
00215   if (verbose) cout << "Is 'Rescue Bad Newton Solve' recognized as a parameter of 'Newton' ... ";
00216   if ( PL_Newton.isParameter( "Rescue Bad Newton Solve" ) ) {  
00217     if (verbose) cout << "yes"<< std::endl;
00218   } else {
00219     if (verbose) cout << "no"<< std::endl;
00220     FailedTests++;
00221   }
00222 
00223   //-----------------------------------------------------------
00224   // Line Search Sublist 
00225   // (if there are no failures, this will be constructed and added)
00226   //-----------------------------------------------------------
00227   if (!FailedTests) {
00228     int ARI = 0, default_step = 0, max_iter_inc = 0, rec_step = 0;
00229     double alpha_factor = 0.0, min_bnds_factor = 0.0, max_bnds_factor = 0.0;
00230     bool force_interp = true, use_cntrs = false;
00231     std::string ls_method = "Polynomial";
00232     // This is to force a char* to be passed into the get method to see if the template
00233     // specialization for char* is working.
00234     char* ls_method_char = const_cast<char *>(ls_method.c_str());
00235     ParameterList PL_My_LineSearch("PL_My_LineSearch");
00236     ls_method = PL_My_LineSearch.get("Method", ls_method_char);
00237     ParameterList& PL_Polynomial = PL_My_LineSearch.sublist("Polynomial");
00238     ARI = PL_Polynomial.get("Allowed Relative Increase", 100 );
00239     alpha_factor = PL_Polynomial.get("Alpha Factor", 0.0001 );
00240     default_step = PL_Polynomial.get("Default Step", 1 );
00241     force_interp = PL_Polynomial.get("Force Interpolation", false );
00242     std::string interp_type = PL_Polynomial.get("Interpolation Type", "Cubic" );
00243     max_bnds_factor = PL_Polynomial.get("Max Bounds Factor", 0.5 );
00244     PL_Polynomial.set("Max Iters", 3 );
00245     max_iter_inc = PL_Polynomial.get("Maximum Iteration for Increase", 0 );
00246     min_bnds_factor = PL_Polynomial.get("Min Bounds Factor", 0.1 );
00247     rec_step = PL_Polynomial.get("Recovery Step", 1 );
00248     std::string rec_step_type = PL_Polynomial.get("Recovery Step Type", "Constant");
00249     std::string suff_dec_cond = PL_Polynomial.get("Sufficient Decrease Condition", "Armijo-Goldstein" );
00250     use_cntrs = PL_Polynomial.get("Use Counters", true );
00251     PL_Main.set("Nonlinear Solver", "Line Search Based");
00252 
00253     //-----------------------------------------------------------
00254     // Set the Line Search Parameter List equal to the one just constructed
00255     //-----------------------------------------------------------
00256     PL_LineSearch.setParameters(PL_My_LineSearch);
00257     ParameterList& PL_My_Polynomial = PL_LineSearch.sublist("Polynomial");
00258     if (verbose) cout<< "Is 'operator=' functional ... ";
00259     if ( PL_My_Polynomial.isParameter("Recovery Step Type") ) {
00260       if (verbose) cout<< "yes" << std::endl;
00261     } else {
00262       if (verbose) cout<< "no" << std::endl;
00263       FailedTests++;
00264     }
00265 
00266     //-----------------------------------------------------------
00267     // Set Copying of parameter sublists and names
00268     //-----------------------------------------------------------
00269 
00270     if (verbose) {
00271       print_break();
00272       if (verbose) cout << "Test copying of sublist\n";
00273       print_break();
00274       PL_Direction.print(cout);
00275     }
00276     {
00277       const ParameterList
00278         &linearSolverPL = PL_Main.sublist("Direction").sublist("Newton").sublist("Line Search");
00279       const ParameterList
00280         linearSolverPL_copy(linearSolverPL);
00281       if (verbose) cout << "linearSolverPL.name() = " << linearSolverPL.name() << endl;
00282       if (verbose) cout << "linearSolverPL_copy.name() = " << linearSolverPL_copy.name() << endl;
00283       if (verbose) cout << "linearSolverPL_copy == linearSolverPL.name() : ";
00284       if (linearSolverPL_copy == linearSolverPL.name()) {
00285         if (verbose) cout << "passed" << endl;
00286       }
00287       else {
00288         if (verbose) cout << "failed" << endl;
00289         FailedTests++;
00290       }
00291     }
00292 
00293     if (verbose) {
00294       print_break();
00295       if (verbose) cout << "General tests\n";
00296       print_break();
00297       PL_Direction.print(cout);
00298     }
00299 
00300     ParameterList Copied_PL_Main(PL_Main);
00301 
00302     if (verbose) cout << "Copied_PL_Main.name() == PL_Main.name() : ";
00303     if (Copied_PL_Main.name() == PL_Main.name()) {
00304       if (verbose) cout << "passed" << endl;
00305     }
00306     else {
00307       if (verbose) cout << "failed" << endl;
00308       FailedTests++;
00309       if (verbose) cout << "Copyed_PL_Main.name() = " << Copied_PL_Main.name() << endl;
00310     }
00311 
00312     if (verbose) cout<< "Is the copy constructor functional ... ";
00313     if ( Copied_PL_Main.isParameter("Nonlinear Solver") ) {
00314       if (verbose) cout<< "yes" << std::endl;
00315     } else {
00316       if (verbose) cout<< "no" << std::endl;
00317       FailedTests++;
00318     }  
00319 
00320     bool tempMeth = true;
00321 
00322     //-----------------------------------------------------------
00323     // Check the templated 'get' method.
00324     //-----------------------------------------------------------
00325     //
00326     //-----------------------------------------------------------
00327     // Retrieve some information from the parameter list using templated "get" method.
00328     // (This will be tested using the INVALID_TEMPLATE_QUALIFIER which indicates whether a
00329     //  non-templated code needs ".template" before the method name )
00330     //-----------------------------------------------------------
00331     int max_iters = 0, max_iters_again = 0;
00332     std::string nonlin_solver;
00333     tempMeth = true;
00334     try {
00335       max_iters = PL_My_Polynomial.INVALID_TEMPLATE_QUALIFIER get<int>("Max Iters");
00336       max_iters_again = Teuchos::getConst(PL_My_Polynomial).INVALID_TEMPLATE_QUALIFIER get<int>("Max Iters");
00337       nonlin_solver = PL_Main.INVALID_TEMPLATE_QUALIFIER get<std::string>("Nonlinear Solver");
00338     }
00339     catch( const Teuchos::Exceptions::InvalidParameter&) { tempMeth = false; }  
00340     if (verbose) {
00341       cout<< "Is the templated 'get' method functional ... "<<std::endl;
00342       cout<< "  Can we retrieve information using the CORRECT variable type ... ";
00343     }
00344     if (tempMeth && max_iters==3) { if (verbose) cout << "yes" << std::endl; }
00345     else { if (verbose) cout << "no" << std::endl; FailedTests++; }
00346     if (verbose) {
00347       cout<< "  Can we retrieve const information using the CORRECT variable type ... ";
00348     }
00349     if (tempMeth && max_iters_again==3) { if (verbose) cout << "yes" << std::endl; }
00350     else { if (verbose) cout << "no" << std::endl; FailedTests++; }
00351 
00352     //-----------------------------------------------------------
00353     // Retrieve some information from the parameter list that we know is a bad "get".
00354     // (This will be tested using the INVALID_TEMPLATE_QUALIFIER which indicates whether a
00355     //  non-templated code needs ".template" before the method name )
00356     //-----------------------------------------------------------
00357     float mbf = 0.0;
00358     tempMeth = false;
00359     try {
00360       mbf = PL_LinSol.INVALID_TEMPLATE_QUALIFIER get<float>( "Tol" );
00361       FailedTests++;
00362     }
00363     catch( const Teuchos::Exceptions::InvalidParameter&) {
00364       tempMeth = true;
00365     }
00366     if (verbose) {
00367       cout<< "  Can we retrieve information using the WRONG variable type ... ";
00368     }
00369     if (tempMeth) { if (verbose) cout << "no" << std::endl; }
00370     else { if (verbose) cout << "yes" << std::endl; }
00371 
00372     //-----------------------------------------------------------
00373     // Retrieve some information from the parameter list using templated "get" method.
00374     // (This will be tested using the INVALID_TEMPLATE_QUALIFIER which indicates whether a
00375     //  non-templated code needs ".template" before the method name )
00376     //-----------------------------------------------------------
00377     tempMeth = true;
00378     try {
00379       max_iters = PL_My_Polynomial.INVALID_TEMPLATE_QUALIFIER get<int>("Max Iters");
00380       nonlin_solver = PL_Main.INVALID_TEMPLATE_QUALIFIER get<std::string>("Nonlinear Solver");
00381     }
00382     catch( const Teuchos::Exceptions::InvalidParameter&) { tempMeth = false; }  
00383     if (verbose) {
00384       cout<< "Is the templated 'get' method functional ... "<<std::endl;
00385       cout<< "  Can we retrieve information using the CORRECT variable type ... ";
00386     }
00387     if (tempMeth && max_iters==3) { if (verbose) cout << "yes" << std::endl; }
00388     else { if (verbose) cout << "no" << std::endl; FailedTests++; }
00389 
00390     //-----------------------------------------------------------
00391     // Retrieve some information from the parameter list that we know is a bad "get".
00392     //-----------------------------------------------------------
00393     tempMeth = false;
00394     try {
00395       mbf = PL_LinSol.INVALID_TEMPLATE_QUALIFIER get<float>( "Tol" );
00396       FailedTests++;
00397     }
00398     catch( const Teuchos::Exceptions::InvalidParameter&) {
00399       tempMeth = true;
00400     }
00401     if (verbose) {
00402       cout<< "  Can we retrieve information using the WRONG variable type ... ";
00403     }
00404     if (tempMeth) { if (verbose) cout << "no" << std::endl; }
00405     else { if (verbose) cout << "yes" << std::endl; }
00406 
00407     //-----------------------------------------------------------
00408     // Check the templated 'getPtr' method.
00409     //-----------------------------------------------------------
00410 
00411     //-----------------------------------------------------------
00412     // Retrieve some information from the parameter list using templated "get" method.
00413     // (This will be tested using the INVALID_TEMPLATE_QUALIFIER which indicates whether a
00414     //  non-templated code needs ".template" before the method name )
00415     //-----------------------------------------------------------
00416     int *max_iters_ptr = 0;
00417     const int *max_iters_ptr_again = 0;
00418     std::string* nonlin_solver_ptr;
00419 
00420     max_iters_ptr = PL_My_Polynomial.INVALID_TEMPLATE_QUALIFIER getPtr<int>("Max Iters");
00421     max_iters_ptr_again = Teuchos::getConst(PL_My_Polynomial).INVALID_TEMPLATE_QUALIFIER getPtr<int>("Max Iters");
00422     nonlin_solver_ptr = PL_Main.INVALID_TEMPLATE_QUALIFIER getPtr<std::string>("Nonlinear Solver");
00423 
00424     if (verbose) {
00425       cout<< "Is the templated 'getPtr' method functional ... "<<std::endl;
00426       cout<< "  Can we retrieve information using the CORRECT variable type ... ";
00427     }
00428     if (max_iters_ptr) {
00429       if ((*max_iters_ptr)==3) {
00430         if (verbose) cout << "yes" << std::endl; 
00431       }
00432       else { if (verbose) cout << "no" << std::endl; FailedTests++; }
00433     }
00434     if (verbose) {
00435       cout<< "  Can we retrieve const information using the CORRECT variable type ... ";
00436     }
00437     if (max_iters_ptr_again) {
00438       if ((*max_iters_ptr_again)==3) {
00439         if (verbose) cout << "yes" << std::endl; 
00440       }
00441       else { if (verbose) cout << "no" << std::endl; FailedTests++; }
00442     }
00443 
00444     //-----------------------------------------------------------
00445     // Retrieve some information from the parameter list that we know is a bad "get".
00446     // (This will be tested using the INVALID_TEMPLATE_QUALIFIER which indicates whether a
00447     //  non-templated code needs ".template" before the method name )
00448     //-----------------------------------------------------------
00449     float* mbf_ptr = 0;
00450 
00451     mbf_ptr = PL_LinSol.INVALID_TEMPLATE_QUALIFIER getPtr<float>( "Tol" );
00452 
00453     if (mbf_ptr)
00454       ++FailedTests;        
00455 
00456     if (verbose) {
00457       cout<< "  Can we retrieve information using the WRONG variable type ... ";
00458     }
00459     if (!mbf_ptr) { if (verbose) cout << "no" << std::endl; }
00460     else { if (verbose) cout << "yes" << std::endl; }
00461 
00462     //-----------------------------------------------------------
00463     // Retrieve some information from the parameter list using templated "get" method.
00464     // (This will be tested using the INVALID_TEMPLATE_QUALIFIER which indicates whether a
00465     //  non-templated code needs ".template" before the method name )
00466     //-----------------------------------------------------------
00467 
00468     max_iters_ptr = PL_My_Polynomial.INVALID_TEMPLATE_QUALIFIER getPtr<int>("Max Iters");
00469     nonlin_solver_ptr = PL_Main.INVALID_TEMPLATE_QUALIFIER getPtr<std::string>("Nonlinear Solver");
00470 
00471     if (verbose) {
00472       cout<< "Is the templated 'getPtr' method functional ... "<<std::endl;
00473       cout<< "  Can we retrieve information using the CORRECT variable type ... ";
00474     }
00475     if (max_iters_ptr) {
00476       if ((*max_iters_ptr)==3) {
00477         if (verbose) cout << "yes" << std::endl; 
00478       }
00479       else { if (verbose) cout << "no" << std::endl; FailedTests++; }
00480     }
00481 
00482     //-----------------------------------------------------------
00483     // Retrieve some information from the parameter list that we know is a bad "get".
00484     // (This will be tested using the INVALID_TEMPLATE_QUALIFIER which indicates whether a
00485     //  non-templated code needs ".template" before the method name )
00486     //-----------------------------------------------------------
00487 
00488     mbf_ptr = PL_LinSol.INVALID_TEMPLATE_QUALIFIER getPtr<float>( "Tol" );
00489 
00490     if (mbf_ptr)
00491       ++FailedTests;        
00492 
00493     if (verbose) {
00494       cout<< "  Can we retrieve information using the WRONG variable type ... ";
00495     }
00496     if (!mbf_ptr) { if (verbose) cout << "no" << std::endl; }
00497     else { if (verbose) cout << "yes" << std::endl; }
00498 
00499     //-----------------------------------------------------------
00500     // Check the 'getParameter' helper function.
00501     //-----------------------------------------------------------
00502     int def_step = 0;
00503     double alpha_fact = 0.0;
00504     tempMeth = true;
00505     try {
00506       def_step = Teuchos::getParameter<int>(PL_Polynomial, "Default Step");
00507       alpha_fact = Teuchos::getParameter<double>(PL_Polynomial, "Alpha Factor");
00508     }
00509     catch( const Teuchos::Exceptions::InvalidParameter&) { tempMeth = false; }
00510     if (verbose && def_step==1) {
00511       cout<< "Is the helper function 'getParameter' functional ... ";
00512     }
00513     if (tempMeth) { if (verbose) cout << "yes" << std::endl; }
00514     else { if (verbose) cout << "no" << std::endl; FailedTests++; }
00515 
00516     //-----------------------------------------------------------
00517     // Check templated isType functionality
00518     // (This will be tested using the INVALID_TEMPLATE_QUALIFIER which indicates whether a
00519     //  non-templated code needs ".template" before the method name )
00520     //-----------------------------------------------------------
00521     bool PT1, PT2, PT3;
00522     PT1 = PL_Polynomial.INVALID_TEMPLATE_QUALIFIER isType<int>("Default Step");
00523     PT2 = PL_Polynomial.INVALID_TEMPLATE_QUALIFIER isType<long int>("Default Step");
00524     PT3 = PL_Polynomial.INVALID_TEMPLATE_QUALIFIER isType<std::string>("Interpolation Type");
00525     if (verbose) {
00526       cout<< "Is the templated 'isType' method functional ... "<<std::endl;
00527       cout<< "  Is the 'Default Step' of type 'int' ... ";
00528     }
00529     if (PT1) { if (verbose) cout<< "yes" << std::endl; }
00530     else { if (verbose) cout<< "no" << std::endl; FailedTests++; }
00531     if (verbose) {
00532       cout<< "  Is the 'Default Step' of type 'long int' ... ";
00533     }
00534     if (PT2) { if (verbose) cout<< "yes" << std::endl; FailedTests++; }
00535     else { if (verbose) cout<< "no (as expected)" << std::endl; }
00536     if (verbose) {
00537       cout<< "  Is the 'Interpolation Type' of type 'std::string' ... ";
00538     }
00539     if (PT3) { if (verbose) cout<< "yes" << std::endl; }
00540     else { if (verbose) cout<< "no" << std::endl; FailedTests++; }
00541 
00542     //-----------------------------------------------------------
00543     // Check the 'isParameterType' helper function.
00544     //-----------------------------------------------------------
00545     bool PT4, PT5;
00546     PT4 = Teuchos::isParameterType<double>(PL_Polynomial, "Max Bounds Factor");
00547     PT5 = Teuchos::isParameterType<float>(PL_Polynomial, "Max Bounds Factor");    
00548     if (verbose) {
00549       cout<< "Is the helper function 'isParameterType' functional ... "<<std::endl;
00550       cout<< "  Is the 'Max Bounds Factor' of type 'double' ... ";
00551     }
00552     if (PT4) { if (verbose) cout<< "yes" <<std::endl; }
00553     else { if (verbose) cout<< "no" << std::endl; FailedTests++; }
00554     if (verbose) {
00555       cout<< "  Is the 'Max Bounds Factor' of type 'float' ... ";
00556     }
00557     if (PT5) { if (verbose) cout<< "yes" <<std::endl; FailedTests++; }
00558     else { if (verbose) cout<< "no (as expected)" << std::endl; }
00559 
00560     //-----------------------------------------------------------
00561     // Can we pass a pointer to a std::vector to the parameter list.
00562     //-----------------------------------------------------------
00563     Teuchos::ArrayRCP<double> tempvec1_arcp = Teuchos::arcp<double>(10);
00564     {
00565       double * tempvec1 = tempvec1_arcp.get();
00566       for (int i=0; i<10; i++) { tempvec1[i] = i; }
00567       PL_Main.set( "Address of Norm Vector", tempvec1 );
00568       double* tempvec2 = Teuchos::getParameter<double*>( PL_Main, "Address of Norm Vector" );
00569       tempvec1[4] = 2.0; tempvec1[6] = 1.0;
00570       if (verbose) {
00571         cout<< "Can we pass a pointer to a std::vector to a parameter list ... ";
00572       }
00573       if ((tempvec2[4]-tempvec1[4])!=0.0 || (tempvec2[6]-tempvec1[6])!=0.0) {
00574         if (verbose) { cout<<"no"<<std::endl; }
00575         FailedTests++;
00576       } else {
00577         if (verbose) { cout<<"yes"<<std::endl; }
00578       }
00579     }
00580 
00581     //-----------------------------------------------------------
00582     // We can add Array<T> objects of various types T as std::string parameters!
00583     //-----------------------------------------------------------
00584     if(verbose) {
00585       print_break();
00586       cout << "Setting int and double array objects as std::string parameters ...\n";
00587       print_break();
00588     }
00589     const Teuchos::Array<int>
00590       intArray = Teuchos::tuple<int>(0,1,2,3,4,5,6);
00591     const Teuchos::Array<double>
00592       doubleArray = Teuchos::tuple<double>(0,1.0,2.0,3.0,4.0,5.0,6.0);
00593     //const Teuchos::Array<bool>
00594     //boolArray = Teuchos::tuple<bool>(true,true,false,false);
00595     Teuchos::setStringParameterFromArray("Int Array",intArray,&PL_Main);
00596     Teuchos::setStringParameterFromArray("Double Array",doubleArray,&PL_Main);
00597     //Teuchos::setStringParameterFromArray("Bool Array",boolArray,&PL_Main);
00598     if(verbose) {
00599       print_break();
00600       cout << "Testing retrieval of set array objects ...\n";
00601       print_break();
00602     }
00603     {
00604 
00605       const Teuchos::Array<int>
00606         readIntArray = Teuchos::getArrayFromStringParameter<int>(PL_Main,"Int Array");
00607       result = readIntArray == intArray;
00608       if(!result) ++FailedTests;
00609       if(verbose)
00610         cout
00611           << "readIntArray = " << readIntArray << " == intArray = " << intArray << " ? "
00612           << (result ? "passed" : "failed")
00613           << "\n";
00614 
00615       const Teuchos::Array<int>
00616         readDoubleAsIntArray = Teuchos::getArrayFromStringParameter<int>(PL_Main,"Double Array");
00617       result = readDoubleAsIntArray == intArray;
00618       if(!result) ++FailedTests;
00619       if(verbose)
00620         cout
00621           << "readDoubleAsIntArray = " << readDoubleAsIntArray << " == intArray = " << intArray << " ? "
00622           << (result ? "passed" : "failed")
00623           << "\n";
00624 
00625 /*
00626       const Teuchos::Array<bool>
00627         readBoolArray = Teuchos::getArrayFromStringParameter<bool>(PL_Main,"Bool Array");
00628       result = readBoolArray == boolArray;
00629       if(!result) ++FailedTests;
00630       if(verbose)
00631         cout
00632           << "readBoolArray = " << readBoolArray << " == boolArray = " << boolArray << " ? "
00633           << (result ? "passed" : "failed")
00634           << "\n";
00635 */
00636 
00637       if(verbose) {
00638         print_break();
00639       }
00640       
00641     }
00642 
00643     //-----------------------------------------------------------
00644     // We can directly set the array strings!
00645     //-----------------------------------------------------------
00646 
00647     if(verbose) {
00648       print_break();
00649       cout << "Setting a array of doubles as a std::string parameter directly ...\n";
00650       print_break();
00651     }
00652 
00653     PL_Main.set(
00654       "Double Array"
00655       ,"  {\n"
00656       "      0.00000\n"
00657       "      ,1.0e0\n"
00658       "      ,0.2e1\n"
00659       "      ,30.0e-1\n"
00660       "      ,4\n"
00661       "      ,5.0000\n"
00662       "      ,6\n"
00663       "  }\n  "
00664       );
00665 
00666     {
00667 
00668       const Teuchos::Array<double>
00669         readDoubleArray = Teuchos::getArrayFromStringParameter<double>(PL_Main,"Double Array");
00670       Teuchos::Array<int>
00671         doubleAsIntArray(readDoubleArray.size());
00672       for(int i=0;i<static_cast<int>(readDoubleArray.size());++i)
00673         doubleAsIntArray[i] = static_cast<int>(readDoubleArray[i]);
00674       result = doubleAsIntArray == intArray;
00675       if(!result) ++FailedTests;
00676       if(verbose)
00677         cout
00678           << "doubleAsIntArray = " << doubleAsIntArray << " == intArray = " << intArray << " ? "
00679           << (result ? "passed" : "failed")
00680           << "\n";
00681 
00682       if(verbose) {
00683         print_break();
00684       }
00685       
00686     }
00687 
00688     //-----------------------------------------------------------
00689     // Can we pass a pointer to a function to the parameter list.
00690     // Use a simple function, pass it in and get it back out ...
00691     // ( HKT 03/23/2004 This test is not supported on Janus )
00692     //-----------------------------------------------------------
00693 #ifndef JANUS_STLPORT 
00694     double (*pt2Function) (double, double);
00695     PL_Main.set( "Address to Simple Function", &Plus );
00696     pt2Function = Teuchos::getParameter<double(*)(double,double)>( PL_Main, "Address to Simple Function" ); 
00697     if (verbose) {
00698       cout<< "Can we pass a pointer to a function to a parameter list ... ";
00699     }
00700     if ( pt2Function( 1.0, 2.0 ) != 3.0 ) {
00701       if (verbose) cout<<"no"<<std::endl;
00702       FailedTests++;
00703     } else {
00704       if (verbose) cout<<"yes"<<std::endl;
00705     }    
00706 #endif
00707   }
00708 
00709   //-----------------------------------------------------------
00710   // We can store and retrieve void* pointers!
00711   //-----------------------------------------------------------
00712   
00713   {
00714     ParameterList pl;
00715     int someInt = 1;
00716     void *someIntPtr = &someInt;
00717     pl.set("Some Pointer", someIntPtr);
00718     void *someIntPtrRtn = getParameter<void*>(pl, "Some Pointer");
00719     TEUCHOS_TEST_FOR_EXCEPT(someIntPtrRtn != someIntPtr);
00720     if (verbose)
00721       cout << "someIntPtrRtn = " << someIntPtrRtn << " == " << someIntPtr << " : ";
00722     if (someIntPtrRtn == someIntPtr) {
00723       if (verbose) cout << "passed\n";
00724     }
00725     else {
00726       if (verbose) cout << "failed\n";
00727       FailedTests++;
00728     }
00729   }
00730 
00731   //-----------------------------------------------------------
00732   // Print using the public iterators
00733   // KL - 7 August 2004
00734   //-----------------------------------------------------------
00735   ParameterList::ConstIterator iter;
00736   
00737   if (verbose) 
00738   {
00739     print_break();
00740     cout << " printing using public iterators " 
00741          << std::endl;
00742     print_break();
00743   }
00744   for (iter = PL_Main.begin(); iter != PL_Main.end(); ++iter)
00745   {
00746     const ParameterEntry& val = PL_Main.entry(iter);
00747     const std::string& name = PL_Main.name(iter);
00748     if (val.isList())
00749     {
00750       if (verbose) cout << name << std::endl;
00751       const ParameterList& sublist = Teuchos::getValue<ParameterList>(val);
00752       ParameterList::ConstIterator i;
00753       for (i=sublist.begin(); i != sublist.end(); ++i)
00754       {
00755         const std::string& nm = sublist.name(i);              
00756         const ParameterEntry& v = sublist.entry(i);
00757         if (v.isList())
00758         {
00759           if (verbose) cout << "  " << nm << std::endl;
00760           if (verbose) Teuchos::getValue<ParameterList>(v).print(cout, 6);
00761         }
00762         else
00763         {
00764           if (verbose) cout << "  " << nm << " " << v << std::endl;
00765         }
00766       }
00767     }
00768     else
00769     {
00770       if (verbose) cout << name << " " << val << std::endl;
00771     }
00772   }
00773 
00774 
00775 #if defined(HAVE_TEUCHOS_EXTENDED)
00776 
00777   try {
00778 
00779     if (verbose) {
00780 
00781       print_break();
00782       cout << "writing to XML std::ostream" << std::endl;
00783       print_break();
00784       writeParameterListToXmlOStream(PL_Main,cout);
00785 
00786       print_break();
00787       cout << "writing to XML file" << std::endl;
00788       print_break();
00789       writeParameterListToXmlFile(PL_Main,"PL_Main.xml");
00790 
00791       print_break();
00792       cout << "reading from XML file" << std::endl;
00793       print_break();
00794       ParameterList readBack;
00795       updateParametersFromXmlFile("PL_Main.xml", inoutArg(readBack));
00796       if (verbose) readBack.print(cout);
00797 
00798       print_break();
00799       cout << "reading from XML std::string" << std::endl;
00800       print_break();
00801       std::ifstream xmlInFile("PL_Main.xml");
00802       std::string xmlStr;
00803       while(!xmlInFile.eof()) {
00804         std::string line;
00805         std::getline(xmlInFile,line);
00806         xmlStr += line + "\n";
00807       }
00808       readBack = ParameterList();
00809       updateParametersFromXmlString(xmlStr, inoutArg(readBack));
00810       if (verbose) readBack.print(cout);
00811 
00812     }
00813 
00814   }
00815   catch(const std::exception& e)
00816   {
00817     if(verbose) {
00818       std::cerr << "caught std::exception:\n\n";
00819       OSTab tab(std::cerr);
00820       std::cerr << e.what() << std::endl;
00821     }
00822     FailedTests++;
00823   }
00824 
00825 #endif // defined(HAVE_TEUCHOS_EXTENDED)
00826 
00827   //-----------------------------------------------------------
00828   // Print out main list
00829   //-----------------------------------------------------------
00830 
00831   if (verbose) {
00832     print_break();
00833     cout << "The Final Parameter List" << std::endl;
00834     print_break();
00835     PL_Main.print(cout);
00836     print_break();
00837     cout << "The unused parameters" << std::endl;
00838     PL_Main.unused(cout);
00839   }
00840 
00841   //-----------------------------------------------------------
00842   // Show error outputs
00843   //-----------------------------------------------------------
00844 
00845   if (verbose) {
00846     print_break();
00847     cout << "Accessing a sublist using the wrong name (should throw a Teuchos::Exceptions::InvalidParameterName std::exception)...\n";
00848     print_break();
00849   }
00850   try {
00851     PL_Main.sublist("Direction").sublist("Newton").sublist("Linear Solvers",true);
00852     if (verbose) cout << "Did not throw std::exception, error!\n";
00853     ++FailedTests;
00854   }
00855   catch(const Teuchos::Exceptions::InvalidParameterName &e) {
00856     std::cerr << "caught expected Teuchos::Exceptions::InvalidParameterName:\n\n";
00857     OSTab tab(std::cerr);
00858     std::cerr << e.what() << std::endl;
00859   }
00860   if (verbose) {
00861     print_break();
00862     cout << "Accessing a parameter using the wrong name (should throw a Teuchos::Exceptions::InvalidParameterName std::exception)...\n";
00863     print_break();
00864   }
00865   try {
00866     Teuchos::getParameter<int>(PL_Main.sublist("Direction").sublist("Newton").sublist("Linear Solver"),"Tolerances");
00867     if (verbose) cout << "Did not throw std::exception, error!\n";
00868     ++FailedTests;
00869   }
00870   catch(const Teuchos::Exceptions::InvalidParameterName &e) {
00871     if(verbose) {
00872       std::cerr << "caught expected Teuchos::Exceptions::InvalidParameterName:\n\n";
00873       OSTab tab(std::cerr);
00874       std::cerr << e.what() << std::endl;
00875     }
00876   }
00877   catch(const std::exception &e) {
00878     if(verbose) {
00879       std::cerr << "caught unexpected std::exception:\n\n";
00880       OSTab tab(std::cerr);
00881       std::cerr << e.what() << std::endl;
00882     }
00883     ++FailedTests;
00884   }
00885 
00886   if (verbose) {
00887     print_break();
00888     cout << "Accessing a parameter using the wrong parameter type (should throw a Teuchos::Exceptions::InvalidParameterType std::exception)...\n";
00889     print_break();
00890   }
00891   try {
00892     Teuchos::getParameter<int>(PL_Main.sublist("Direction").sublist("Newton").sublist("Linear Solver"),"Tolerance");
00893     if (verbose) cout << "Did not throw std::exception, error!\n";
00894     ++FailedTests;
00895   }
00896   catch(const Teuchos::Exceptions::InvalidParameterType &e) {
00897     if(verbose) {
00898       std::cerr << "caught expected Teuchos::Exceptions::InvalidParameterType:\n\n";
00899       OSTab tab(std::cerr);
00900       std::cerr << e.what() << std::endl;
00901     }
00902   }
00903   catch(const std::exception &e) {
00904     if(verbose) {
00905       std::cerr << "caught unexpected std::exception:\n\n";
00906       OSTab tab(std::cerr);
00907       std::cerr << e.what() << std::endl;
00908     }
00909     ++FailedTests;
00910   }
00911 
00912   //-----------------------------------------------------------
00913   // Validate the parameter list
00914   //-----------------------------------------------------------
00915 
00916   // Create a validator version of PL_Main that we will validate against!
00917   Teuchos::ParameterList PL_Main_valid("PL_Main_copy");
00918   PL_Main_valid.setParameters(PL_Main);
00919 
00920   // Create a validator for the "Nonlinear Solver" parameter
00921   Teuchos::setStringToIntegralParameter<int>(
00922     "Nonlinear Solver", "Line Search Based",
00923     "Selects the type of nonlinear solver to use",
00924     Teuchos::tuple<std::string>("Line Search Based","Trust Region Based"),
00925     &PL_Main
00926     );
00927 
00928 /*    
00929   Teuchos::RCP<Teuchos::StringToIntegralParameterEntryValidator<int> >
00930     nonlinearSolverValidator = rcp(
00931     new Teuchos::StringToIntegralParameterEntryValidator<int>(
00932       Teuchos::tuple<std::string>("Line Search Based","Trust Region Based")
00933       ,"Nonlinear Solver"
00934       )
00935     );
00936   PL_Main_valid.set(
00937     "Nonlinear Solver", "Line Search Based"
00938     ,"Selects the type of nonlinear solver to use"
00939     ,nonlinearSolverValidator
00940     );
00941 */
00942 
00943   // Create a validator for the parameter "Line Search"->"Polynomial"->"Max Iters"
00944   // that accepts an 'int', a 'double' or a 'std::string' value!
00945   typedef Teuchos::AnyNumberParameterEntryValidator::AcceptedTypes AcceptedTypes;
00946   Teuchos::RCP<Teuchos::AnyNumberParameterEntryValidator>
00947     linesearchMaxItersValiator = rcp(
00948       new Teuchos::AnyNumberParameterEntryValidator(
00949         Teuchos::AnyNumberParameterEntryValidator::PREFER_INT, // Not used here!
00950         AcceptedTypes(false).allowInt(true).allowDouble(true).allowString(true)
00951         )
00952       );
00953   PL_Main_valid.sublist("Line Search").sublist("Polynomial").set(
00954     "Max Iters",3
00955     ,"The maximum number of inner linear search iterations allowed."
00956     ,linesearchMaxItersValiator
00957     );
00958 
00959   // Create a validator for the parameter "Direction"->"Newton"->"Linear Solver"->"Tol"
00960   // that accepts a 'double' or a 'std::string' value!
00961   typedef Teuchos::AnyNumberParameterEntryValidator::AcceptedTypes AcceptedTypes;
00962   Teuchos::RCP<Teuchos::AnyNumberParameterEntryValidator>
00963     linSolveTolValidator = rcp(
00964       new Teuchos::AnyNumberParameterEntryValidator(
00965         Teuchos::AnyNumberParameterEntryValidator::PREFER_INT, // Not used here!
00966         AcceptedTypes(false).allowDouble(true).allowString(true)
00967         )
00968       );
00969   PL_Main_valid.sublist("Direction",true).sublist("Newton",true)
00970     .sublist("Linear Solver",true).set(
00971       "Tol", double(1e-5)
00972       ,"Select the linear solve tolerance"
00973     ,linSolveTolValidator
00974     );
00975 
00976   if (verbose) {
00977     print_break();
00978     cout << "Validating the parameter list against itself (should not throw std::exception)...\n";
00979     print_break();
00980   }
00981   try {
00982     PL_Main.validateParameters(PL_Main_valid);
00983     if (verbose) cout << "Did not throw std::exception, success!\n\n";
00984   }
00985   catch(const std::exception &e) {
00986     if(verbose) {
00987       std::cerr << "caught unexpected std::exception:\n\n";
00988       OSTab tab(std::cerr);
00989       std::cerr << e.what() << std::endl;
00990     }
00991     ++FailedTests;
00992   }
00993 
00994   if (verbose) {
00995     print_break();
00996     cout << "Adding an invalid parameter type then validating (should throw a Teuchos::Exceptions::InvalidParameterType std::exception)...\n";
00997     print_break();
00998   }
00999   try {
01000     PL_Main.sublist("Line Search").sublist("Polynomial").set("Max Iters",(short int)(3)); // Should be an int!
01001     PL_Main.validateParameters(PL_Main_valid);
01002     if (verbose) cout << "Did not throw std::exception, error!\n";
01003     ++FailedTests;
01004   }
01005   catch(const Teuchos::Exceptions::InvalidParameterType &e) {
01006     if(verbose) {
01007       std::cerr << "caught expected Teuchos::Exceptions::InvalidParameterType:\n\n";
01008       OSTab tab(std::cerr);
01009       std::cerr << e.what() << std::endl;
01010     }
01011   }
01012   catch(const std::exception &e) {
01013     if(verbose) {
01014       std::cerr << "caught unexpected std::exception:\n\n";
01015       OSTab tab(std::cerr);
01016       std::cerr << e.what() << std::endl;
01017     }
01018     ++FailedTests;
01019   }
01020   PL_Main.sublist("Line Search").sublist("Polynomial").set("Max Iters",3); // Put back the valid int!
01021 
01022   if (verbose) {
01023     print_break();
01024     cout << "Adding an invalid parameter name then validating (should throw a Teuchos::Exceptions::InvalidParameterName std::exception)...\n";
01025     print_break();
01026   }
01027   try {
01028     PL_Main.sublist("Line Search").sublist("Polynomial").set("Max Iter",10);
01029     PL_Main.validateParameters(PL_Main_valid);
01030     if (verbose) cout << "Did not throw std::exception, error!\n";
01031     ++FailedTests;
01032   }
01033   catch(const Teuchos::Exceptions::InvalidParameterName &e) {
01034     if(verbose) {
01035       std::cerr << "caught expected Teuchos::Exceptions::InvalidParameterName:\n\n";
01036       OSTab tab(std::cerr);
01037       std::cerr << e.what() << std::endl;
01038     }
01039   }
01040   catch(const std::exception &e) {
01041     if(verbose) {
01042       std::cerr << "caught unexpected std::exception:\n\n";
01043       OSTab tab(std::cerr);
01044       std::cerr << e.what() << std::endl;
01045     }
01046     ++FailedTests;
01047   }
01048   PL_Main.sublist("Line Search").sublist("Polynomial").remove("Max Iter");
01049 
01050   if (verbose) {
01051     print_break();
01052     cout << "Adding an invalid parameter type then validating using validator (should throw a Teuchos::Exceptions::InvalidParameterType std::exception)...\n";
01053     print_break();
01054   }
01055   try {
01056     PL_Main.set("Nonlinear Solver",int(0)); // Should be a std::string!
01057     PL_Main.validateParameters(PL_Main_valid);
01058     if (verbose) cout << "Did not throw std::exception, error!\n";
01059     ++FailedTests;
01060   }
01061   catch(const Teuchos::Exceptions::InvalidParameterType &e) {
01062     if(verbose) {
01063       std::cerr << "caught expected Teuchos::Exceptions::InvalidParameterType:\n\n";
01064       OSTab tab(std::cerr);
01065       std::cerr << e.what() << std::endl;
01066     }
01067   }
01068   catch(const std::exception &e) {
01069     if(verbose) {
01070       std::cerr << "caught unexpected std::exception:\n\n";
01071       OSTab tab(std::cerr);
01072       std::cerr << e.what() << std::endl;
01073     }
01074     ++FailedTests;
01075   }
01076   PL_Main.set("Nonlinear Solver","Line Search Based"); // Put back the valid value!
01077 
01078   if (verbose) {
01079     print_break();
01080     cout << "Adding an invalid parameter value then validating using validator (should throw a Teuchos::Exceptions::InvalidParameterValue std::exception)...\n";
01081     print_break();
01082   }
01083   try {
01084     PL_Main.set("Nonlinear Solver","LineSearch Based"); // Should be "Line Search Based"!
01085     PL_Main.validateParameters(PL_Main_valid);
01086     if (verbose) cout << "Did not throw std::exception, error!\n";
01087     ++FailedTests;
01088   }
01089   catch(const Teuchos::Exceptions::InvalidParameterValue &e) {
01090     if(verbose) {
01091       std::cerr << "caught expected Teuchos::Exceptions::InvalidParameterValue:\n\n";
01092       OSTab tab(std::cerr); std::cerr << e.what() << std::endl;
01093     }
01094   }
01095   catch(const std::exception &e) {
01096     if(verbose) {
01097       std::cerr << "caught unexpected std::exception:\n\n";
01098       OSTab tab(std::cerr); std::cerr << e.what() << std::endl;
01099     }
01100     ++FailedTests;
01101   }
01102   PL_Main.set("Nonlinear Solver","Line Search Based"); // Put back the valid value!
01103 
01104   if (verbose) {
01105     print_break();
01106     cout << "Use the validator to access integral value (should *not* throw std::exception)...\n";
01107     print_break();
01108   }
01109   try {
01110     const int
01111       nonlinearSolverValue = Teuchos::getIntegralValue<int>(PL_Main,"Nonlinear Solver");
01112     const bool
01113       l_result = (nonlinearSolverValue == 0);
01114     cout
01115       << "Read value = " << nonlinearSolverValue << " == 0 : "
01116       << ( l_result ? "passed" : "failed") << "\n";
01117     if(!l_result) ++FailedTests;
01118   }
01119   catch(const std::exception &e) {
01120     if(verbose) {
01121       std::cerr << "caught unexpected std::exception:\n\n";
01122       OSTab tab(std::cerr); std::cerr << e.what() << std::endl;
01123     }
01124     ++FailedTests;
01125   }
01126 
01127   if (verbose) {
01128     print_break();
01129     cout << "Use the validator to access std::string value (should *not* throw std::exception)...\n";
01130     print_break();
01131   }
01132   try {
01133     const std::string
01134       nonlinearSolverValue = Teuchos::getStringValue<int>(PL_Main,"Nonlinear Solver");
01135     const bool
01136       l_result = (nonlinearSolverValue == "Line Search Based");
01137     cout
01138       << "Read value = \"" << nonlinearSolverValue << " == \"Line Search Based\" : "
01139       << ( l_result ? "passed" : "failed") << "\n";
01140     if(!l_result) ++FailedTests;
01141   }
01142   catch(const std::exception &e) {
01143     if(verbose) {
01144       std::cerr << "caught unexpected std::exception:\n\n";
01145       OSTab tab(std::cerr); std::cerr << e.what() << std::endl;
01146     }
01147     ++FailedTests;
01148   }
01149 
01150   //-----------------------------------------------------------
01151   // Validate and set defaults
01152   //-----------------------------------------------------------
01153 
01154   // Set the default parameters for an emplty list
01155   ParameterList validatedPL;
01156 
01157   if (verbose) {
01158     print_break();
01159     cout << "Validating and setting defaults for an empty parameter list (should not throw) ...\n";
01160     print_break();
01161   }
01162   try {
01163     validatedPL.validateParametersAndSetDefaults(PL_Main_valid);
01164     if (verbose) cout << "Did not throw std::exception, success!\n\n";
01165   }
01166   catch(const std::exception &e) {
01167     if(verbose) {
01168       std::cerr << "caught unexpected std::exception:\n\n";
01169       OSTab tab(std::cerr); std::cerr << e.what() << std::endl;
01170     }
01171     ++FailedTests;
01172   }
01173 
01174   if (verbose) {
01175     print_break();
01176     cout << "Parameter list with defaults set:" << std::endl;
01177     print_break();
01178     validatedPL.print(cout,PLPrintOptions().showTypes(true).showDoc(true));
01179     print_break();
01180   }
01181 
01182   if (verbose) {
01183     print_break();
01184     cout << "Checking that validatedPL and PL_Main_valid have the same values : ";
01185   }
01186   result = haveSameValues(validatedPL,PL_Main_valid);
01187   if(!result)
01188     ++FailedTests;
01189   if (verbose) {
01190     cout << ( result ? "passed" : "failed" ) << "\n";
01191     print_break();
01192   }
01193 
01194   //
01195   // Testing access of numbers using validator where validator is not buried
01196   // in the parameter
01197   //
01198 
01199   for( int type_i = 0; type_i < 3; ++type_i ) {
01200 
01201     ParameterList &Polynomial_sublist
01202       = PL_Main.sublist("Line Search",true).sublist("Polynomial",true);
01203     
01204     std::string typeName;
01205 
01206     // Set the input type
01207 
01208     switch(type_i) {
01209       case 0:
01210         typeName = "int";
01211         Polynomial_sublist.set("Max Iters",(int)(3));
01212         break;
01213       case 1:
01214         typeName = "double";
01215         Polynomial_sublist.set("Max Iters",(double)(3.0));
01216         break;
01217       case 2:
01218         typeName = "std::string";
01219         Polynomial_sublist.set("Max Iters",(std::string)("3"));
01220         break;
01221       default:
01222         TEUCHOS_TEST_FOR_EXCEPT(true);
01223     }
01224 
01225     // Extract using external validator
01226 
01227     if (verbose) {
01228       print_break();
01229       cout << "Use the external number validator to access a "<<typeName<<" as an int ...\n";
01230       print_break();
01231     }
01232     try {
01233       const int
01234         lineserchMaxIters
01235         = linesearchMaxItersValiator->getInt(
01236           PL_Main.sublist("Line Search",true).sublist("Polynomial",true)
01237           ,"Max Iters",0
01238           );
01239       const bool
01240         l_result = (lineserchMaxIters == int(3));
01241       cout
01242         << "Read value = " << lineserchMaxIters << " == 3 : "
01243         << ( l_result ? "passed" : "failed") << "\n";
01244       if(!l_result) ++FailedTests;
01245     }
01246     catch(const std::exception &e) {
01247       if(verbose) {
01248         std::cerr << "caught unexpected std::exception:\n\n";
01249         OSTab tab(std::cerr); std::cerr << e.what() << std::endl;
01250       }
01251       ++FailedTests;
01252     }
01253 
01254     if (verbose) {
01255       print_break();
01256       cout << "Use the external number validator to access a "<<typeName<<" as a double ...\n";
01257       print_break();
01258     }
01259     try {
01260       const double
01261         lineserchMaxIters
01262         = linesearchMaxItersValiator->getDouble(
01263           PL_Main.sublist("Line Search",true).sublist("Polynomial",true)
01264           ,"Max Iters",0.0
01265           );
01266       const bool
01267         l_result = (lineserchMaxIters == double(3.0));
01268       cout
01269         << "Read value = " << lineserchMaxIters << " == 3 : "
01270         << ( l_result ? "passed" : "failed") << "\n";
01271       if(!l_result) ++FailedTests;
01272     }
01273     catch(const std::exception &e) {
01274       if(verbose) {
01275         std::cerr << "caught unexpected std::exception:\n\n";
01276         OSTab tab(std::cerr); std::cerr << e.what() << std::endl;
01277       }
01278       ++FailedTests;
01279     }
01280 
01281     if (verbose) {
01282       print_break();
01283       cout << "Use the external number validator to access a "<<typeName<<" as a std::string ...\n";
01284       print_break();
01285     }
01286     try {
01287       const std::string
01288         lineserchMaxIters
01289         = linesearchMaxItersValiator->getString(
01290           PL_Main.sublist("Line Search",true).sublist("Polynomial",true)
01291           ,"Max Iters","0"
01292           );
01293       const bool
01294         l_result = (lineserchMaxIters == "3");
01295       cout
01296         << "Read value = \"" << lineserchMaxIters << "\" == \"3\" : "
01297         << ( l_result ? "passed" : "failed") << "\n";
01298       if(!l_result) ++FailedTests;
01299     }
01300     catch(const std::exception &e) {
01301       if(verbose) {
01302         std::cerr << "caught unexpected std::exception:\n\n";
01303         OSTab tab(std::cerr); std::cerr << e.what() << std::endl;
01304       }
01305       ++FailedTests;
01306     }
01307 
01308     // Extract using nonmember functions
01309 
01310     if (verbose) {
01311       print_break();
01312       cout << "Use the nomember help function to access a "<<typeName<<" as an int ...\n";
01313       print_break();
01314     }
01315     try {
01316       const int
01317         lineserchMaxIters
01318         = Teuchos::getIntParameter(
01319           PL_Main.sublist("Line Search",true).sublist("Polynomial",true)
01320           ,"Max Iters"
01321           );
01322       const bool
01323         l_result = (lineserchMaxIters == int(3));
01324       cout
01325         << "Read value = " << lineserchMaxIters << " == 3 : "
01326         << ( l_result ? "passed" : "failed") << "\n";
01327       if(!l_result) ++FailedTests;
01328     }
01329     catch(const std::exception &e) {
01330       if(verbose) {
01331         std::cerr << "caught unexpected std::exception:\n\n";
01332         OSTab tab(std::cerr); std::cerr << e.what() << std::endl;
01333       }
01334       ++FailedTests;
01335     }
01336 
01337     if (verbose) {
01338       print_break();
01339       cout << "Use the nomember help function to access a "<<typeName<<" as a double ...\n";
01340       print_break();
01341     }
01342     try {
01343       const double
01344         lineserchMaxIters
01345         = Teuchos::getDoubleParameter(
01346           PL_Main.sublist("Line Search",true).sublist("Polynomial",true)
01347           ,"Max Iters"
01348           );
01349       const bool
01350         l_result = (lineserchMaxIters == double(3.0));
01351       cout
01352         << "Read value = " << lineserchMaxIters << " == 3 : "
01353         << ( l_result ? "passed" : "failed") << "\n";
01354       if(!l_result) ++FailedTests;
01355     }
01356     catch(const std::exception &e) {
01357       if(verbose) {
01358         std::cerr << "caught unexpected std::exception:\n\n";
01359         OSTab tab(std::cerr); std::cerr << e.what() << std::endl;
01360       }
01361       ++FailedTests;
01362     }
01363 
01364     if (verbose) {
01365       print_break();
01366       cout << "Use the nomember help function to access a "<<typeName<<" as a std::string ...\n";
01367       print_break();
01368     }
01369     try {
01370       const std::string
01371         lineserchMaxIters
01372         = Teuchos::getNumericStringParameter(
01373           PL_Main.sublist("Line Search",true).sublist("Polynomial",true)
01374           ,"Max Iters"
01375           );
01376       const bool
01377         l_result = (lineserchMaxIters == "3");
01378       cout
01379         << "Read value = \"" << lineserchMaxIters << "\" == \"3\" : "
01380         << ( l_result ? "passed" : "failed") << "\n";
01381       if(!l_result) ++FailedTests;
01382     }
01383     catch(const std::exception &e) {
01384       if(verbose) {
01385         std::cerr << "caught unexpected std::exception:\n\n";
01386         OSTab tab(std::cerr); std::cerr << e.what() << std::endl;
01387       }
01388       ++FailedTests;
01389     }
01390 
01391   }
01392 
01393   //
01394   // Testing access of numbers using validator where validator is buried in
01395   // the parameter
01396   //
01397 
01398   for( int type_i = 0; type_i < 3; ++type_i ) {
01399 
01400     ParameterList &Polynomial_sublist
01401       = PL_Main.sublist("Line Search",true).sublist("Polynomial",true);
01402     
01403     std::string typeName;
01404 
01405     // Set the input type
01406 
01407     switch(type_i) {
01408       case 0:
01409         typeName = "int";
01410         Teuchos::setIntParameter("Max Iters",3,"",&Polynomial_sublist);
01411         break;
01412       case 1:
01413         typeName = "double";
01414         Teuchos::setDoubleParameter("Max Iters",3.0,"",&Polynomial_sublist);
01415         break;
01416       case 2:
01417         typeName = "std::string";
01418         Teuchos::setNumericStringParameter("Max Iters","3","",&Polynomial_sublist);
01419         break;
01420       default:
01421         TEUCHOS_TEST_FOR_EXCEPT(true);
01422     }
01423 
01424     // Extract using nonmember functions (which should use the internal validator)
01425 
01426     if (verbose) {
01427       print_break();
01428       cout << "Use the nomember help function to access a "<<typeName<<" as an int ...\n";
01429       print_break();
01430     }
01431     try {
01432       const int
01433         lineserchMaxIters
01434         = Teuchos::getIntParameter(
01435           PL_Main.sublist("Line Search",true).sublist("Polynomial",true)
01436           ,"Max Iters"
01437           );
01438       const bool
01439         l_result = (lineserchMaxIters == int(3));
01440       cout
01441         << "Read value = " << lineserchMaxIters << " == 3 : "
01442         << ( l_result ? "passed" : "failed") << "\n";
01443       if(!l_result) ++FailedTests;
01444     }
01445     catch(const std::exception &e) {
01446       if(verbose) {
01447         std::cerr << "caught unexpected std::exception:\n\n";
01448         OSTab tab(std::cerr); std::cerr << e.what() << std::endl;
01449       }
01450       ++FailedTests;
01451     }
01452 
01453     if (verbose) {
01454       print_break();
01455       cout << "Use the nomember help function to access a "<<typeName<<" as a double ...\n";
01456       print_break();
01457     }
01458     try {
01459       const double
01460         lineserchMaxIters
01461         = Teuchos::getDoubleParameter(
01462           PL_Main.sublist("Line Search",true).sublist("Polynomial",true)
01463           ,"Max Iters"
01464           );
01465       const bool
01466         l_result = (lineserchMaxIters == double(3.0));
01467       cout
01468         << "Read value = " << lineserchMaxIters << " == 3 : "
01469         << ( l_result ? "passed" : "failed") << "\n";
01470       if(!l_result) ++FailedTests;
01471     }
01472     catch(const std::exception &e) {
01473       if(verbose) {
01474         std::cerr << "caught unexpected std::exception:\n\n";
01475         OSTab tab(std::cerr); std::cerr << e.what() << std::endl;
01476       }
01477       ++FailedTests;
01478     }
01479 
01480     if (verbose) {
01481       print_break();
01482       cout << "Use the nomember help function to access a "<<typeName<<" as a std::string ...\n";
01483       print_break();
01484     }
01485     try {
01486       const std::string
01487         lineserchMaxIters
01488         = Teuchos::getNumericStringParameter(
01489           PL_Main.sublist("Line Search",true).sublist("Polynomial",true)
01490           ,"Max Iters"
01491           );
01492       const bool
01493         l_result = (lineserchMaxIters == "3");
01494       cout
01495         << "Read value = \"" << lineserchMaxIters << "\" == \"3\" : "
01496         << ( l_result ? "passed" : "failed") << "\n";
01497       if(!l_result) ++FailedTests;
01498     }
01499     catch(const std::exception &e) {
01500       if(verbose) {
01501         std::cerr << "caught unexpected std::exception:\n\n";
01502         OSTab tab(std::cerr); std::cerr << e.what() << std::endl;
01503       }
01504       ++FailedTests;
01505     }
01506 
01507   }
01508 
01509   //
01510   // Testing access of numbers where correct number is set using
01511   // validateParametersAndSetDefaults(...) with no special access.
01512   //
01513 
01514   for( int type_i = 0; type_i < 3; ++type_i ) {
01515 
01516     ParameterList valid_PL_Main(PL_Main);
01517 
01518     ParameterList &Polynomial_sublist
01519       = PL_Main.sublist("Line Search",true).sublist("Polynomial",true);
01520     
01521     std::string typeName;
01522 
01523     // Set the input type
01524 
01525     switch(type_i) {
01526       case 0:
01527         typeName = "int";
01528         Teuchos::setIntParameter("Max Iters",3,"",&Polynomial_sublist);
01529         break;
01530       case 1:
01531         typeName = "double";
01532         Teuchos::setDoubleParameter("Max Iters",3.0,"",&Polynomial_sublist);
01533         break;
01534       case 2:
01535         typeName = "std::string";
01536         Teuchos::setNumericStringParameter("Max Iters","3","",&Polynomial_sublist);
01537         break;
01538       default:
01539         TEUCHOS_TEST_FOR_EXCEPT(true);
01540     }
01541 
01542     // Extract using nonmember functions (which should use the internal validator)
01543 
01544     if (verbose) {
01545       print_break();
01546       cout << "Use validateParemetersAndSetDefaults(...) to access a "<<typeName<<" as an int ...\n";
01547       print_break();
01548     }
01549     try {
01550       Teuchos::setIntParameter(
01551         "Max Iters", 0, "",
01552         &valid_PL_Main.sublist("Line Search",true).sublist("Polynomial",true)
01553         );
01554       ParameterList copied_PL_Main(PL_Main);
01555       copied_PL_Main.validateParametersAndSetDefaults(valid_PL_Main);
01556       const int
01557         lineserchMaxIters
01558         = Teuchos::getParameter<int>(
01559           copied_PL_Main.sublist("Line Search",true).sublist("Polynomial",true)
01560           ,"Max Iters"
01561           );
01562       const bool
01563         l_result = (lineserchMaxIters == int(3));
01564       cout
01565         << "Read value = " << lineserchMaxIters << " == 3 : "
01566         << ( l_result ? "passed" : "failed") << "\n";
01567       if(!l_result) ++FailedTests;
01568     }
01569     catch(const std::exception &e) {
01570       if(verbose) {
01571         std::cerr << "caught unexpected std::exception:\n\n";
01572         OSTab tab(std::cerr); std::cerr << e.what() << std::endl;
01573       }
01574       ++FailedTests;
01575     }
01576 
01577     if (verbose) {
01578       print_break();
01579       cout << "Use validateParemetersAndSetDefaults(...) to access a "<<typeName<<" as a double ...\n";
01580       print_break();
01581     }
01582     try {
01583       Teuchos::setDoubleParameter(
01584         "Max Iters", 0.0, "",
01585         &valid_PL_Main.sublist("Line Search",true).sublist("Polynomial",true)
01586         );
01587       ParameterList copied_PL_Main(PL_Main);
01588       copied_PL_Main.validateParametersAndSetDefaults(valid_PL_Main);
01589       const double
01590         lineserchMaxIters
01591         = Teuchos::getParameter<double>(
01592           copied_PL_Main.sublist("Line Search",true).sublist("Polynomial",true)
01593           ,"Max Iters"
01594           );
01595       const bool
01596         l_result = (lineserchMaxIters == double(3.0));
01597       cout
01598         << "Read value = " << lineserchMaxIters << " == 3 : "
01599         << ( l_result ? "passed" : "failed") << "\n";
01600       if(!l_result) ++FailedTests;
01601     }
01602     catch(const std::exception &e) {
01603       if(verbose) {
01604         std::cerr << "caught unexpected std::exception:\n\n";
01605         OSTab tab(std::cerr); std::cerr << e.what() << std::endl;
01606       }
01607       ++FailedTests;
01608     }
01609 
01610     if (verbose) {
01611       print_break();
01612       cout << "Use validateParemetersAndSetDefaults(...) to access a "<<typeName<<" as a std::string ...\n";
01613       print_break();
01614     }
01615     try {
01616       Teuchos::setNumericStringParameter(
01617         "Max Iters", "0", "",
01618         &valid_PL_Main.sublist("Line Search",true).sublist("Polynomial",true)
01619         );
01620       ParameterList copied_PL_Main(PL_Main);
01621       copied_PL_Main.validateParametersAndSetDefaults(valid_PL_Main);
01622       const std::string
01623         lineserchMaxIters
01624         = Teuchos::getParameter<std::string>(
01625           copied_PL_Main.sublist("Line Search",true).sublist("Polynomial",true)
01626           ,"Max Iters"
01627           );
01628       const bool
01629         l_result = (lineserchMaxIters == "3");
01630       cout
01631         << "Read value = \"" << lineserchMaxIters << "\" == \"3\" : "
01632         << ( l_result ? "passed" : "failed") << "\n";
01633       if(!l_result) ++FailedTests;
01634     }
01635     catch(const std::exception &e) {
01636       if(verbose) {
01637         std::cerr << "caught unexpected std::exception:\n\n";
01638         OSTab tab(std::cerr); std::cerr << e.what() << std::endl;
01639       }
01640       ++FailedTests;
01641     }
01642 
01643   }
01644 
01645   if (verbose) {
01646     print_break();
01647     cout << "Adding an invalid sublist then validating (should throw a Teuchos::Exceptions::InvalidParameterName std::exception)...\n";
01648     print_break();
01649   }
01650   try {
01651     PL_Main.sublist("Line Search").sublist("Polynomials").set("Max Iters",3); // param correct, sublist wrong
01652     PL_Main.validateParameters(PL_Main_valid);
01653     if (verbose) cout << "Did not throw std::exception, error!\n";
01654     ++FailedTests;
01655   }
01656   catch(const Teuchos::Exceptions::InvalidParameterName &e) {
01657     if(verbose) {
01658       std::cerr << "caught expected Teuchos::Exceptions::InvalidParameterName:\n\n";
01659       OSTab tab(std::cerr); std::cerr << e.what() << std::endl;
01660     }
01661   }
01662   catch(const std::exception &e) {
01663     if(verbose) {
01664       std::cerr << "caught unexpected std::exception:\n\n";
01665       OSTab tab(std::cerr); std::cerr << e.what() << std::endl;
01666     }
01667     ++FailedTests;
01668   }
01669   PL_Main.sublist("Line Search").remove("Polynomials");
01670 
01671   if (verbose) {
01672     print_break();
01673     cout << "Validating only the top level list (should not throw std::exception)...\n";
01674     print_break();
01675   }
01676   try {
01677     PL_Main.validateParameters(PL_Main_valid,0);
01678     if (verbose) cout << "Did not throw std::exception, success!\n\n";
01679   }
01680   catch(const std::exception &e) {
01681     if(verbose) {
01682       std::cerr << "caught unexpected std::exception:\n\n";
01683       OSTab tab(std::cerr); std::cerr << e.what() << std::endl;
01684     }
01685     ++FailedTests;
01686   }
01687 
01688   //-----------------------------------------------------------
01689   // Compare lists
01690   //-----------------------------------------------------------
01691 
01692   if (verbose) {
01693     print_break();
01694     cout << "Checking that PL_Main == PL_Main == true : ";
01695   }
01696   result = (PL_Main == PL_Main);
01697   if(!result)
01698     ++FailedTests;
01699   if (verbose) {
01700     cout << ( result ? "passed" : "failed" ) << "\n";
01701     print_break();
01702   }
01703 
01704   if (verbose) {
01705     print_break();
01706     cout << "Checking that PL_Main != PL_Main == false : ";
01707   }
01708   result = !(PL_Main != PL_Main);
01709   if(!result)
01710     ++FailedTests;
01711   if (verbose) {
01712     cout << ( result ? "passed" : "failed" ) << "\n";
01713     print_break();
01714   }
01715 
01716   if (verbose) {
01717     print_break();
01718     cout << "Checking that PL_Main and PL_Main have the same values : ";
01719   }
01720   result = haveSameValues(PL_Main,PL_Main);
01721   if(!result)
01722     ++FailedTests;
01723   if (verbose) {
01724     cout << ( result ? "passed" : "failed" ) << "\n";
01725     print_break();
01726   }
01727 
01728   if (verbose) {
01729     print_break();
01730     cout << "Create copy PL_Main_copy, change PL_Main_copy, and check that PL_Main != PL_Main == true : ";
01731   }
01732   ParameterList PL_Main_copy(PL_Main);
01733   PL_Main_copy.sublist("Line Search",true).sublist("Polynomial",true).set("Max Iters",100); // Not the default!
01734   result = (PL_Main_copy != PL_Main);
01735   if(!result)
01736     ++FailedTests;
01737   if (verbose) {
01738     cout << ( result ? "passed" : "failed" ) << "\n";
01739     print_break();
01740   }
01741 
01742   //-----------------------------------------------------------
01743   // Print out main list showing the types
01744   //-----------------------------------------------------------
01745 
01746   if (verbose) {
01747     print_break();
01748     cout << "The Final Parameter List with Types and Documentation" << std::endl;
01749     print_break();
01750     PL_Main.print(cout,PLPrintOptions().showTypes(true).showDoc(true));
01751     print_break();
01752     cout << "The unused parameters" << std::endl;
01753     PL_Main.unused(cout);
01754     print_break();
01755     cout << "Number of Failed Tests : " << FailedTests << std::endl;
01756     print_break();
01757   }
01758 
01759   //-----------------------------------------------------------
01760   // Return -1 if there are any failed tests, 
01761   // else 0 will be returned indicating a clean finish!  
01762   //-----------------------------------------------------------
01763 
01764   } // end try
01765   TEUCHOS_STANDARD_CATCH_STATEMENTS(verbose,std::cerr,success);
01766   if(!success) ++FailedTests;
01767 
01768   if ( FailedTests > 0 ) { 
01769     cout << "End Result: TEST FAILED" << std::endl;
01770     return 1; // Can't return negative numbers from main()!
01771   }
01772 
01773   if ( FailedTests == 0 )
01774     cout << "End Result: TEST PASSED" << std::endl;
01775 
01776   return 0;
01777 
01778 }
01779 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines