MoochoPack_MoochoSolver.cpp

00001 // @HEADER
00002 // ***********************************************************************
00003 // 
00004 // Moocho: Multi-functional Object-Oriented arCHitecture for Optimization
00005 //                  Copyright (2003) 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 // This library is free software; you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as
00012 // published by the Free Software Foundation; either version 2.1 of the
00013 // License, or (at your option) any later version.
00014 //  
00015 // This library is distributed in the hope that it will be useful, but
00016 // WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 // Lesser General Public License for more details.
00019 //  
00020 // You should have received a copy of the GNU Lesser General Public
00021 // License along with this library; if not, write to the Free Software
00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00023 // USA
00024 // Questions? Contact Roscoe A. Bartlett (rabartl@sandia.gov) 
00025 // 
00026 // ***********************************************************************
00027 // @HEADER
00028 
00029 #include "MoochoPack_MoochoSolver.hpp"
00030 
00031 #include "MoochoPack_NLPAlgoConfigMamaJama.hpp"
00032 #include "MoochoPack_NLPAlgoConfigIP.hpp"
00033 
00034 #include "MoochoPack_NLPSolverClientInterfaceSetOptions.hpp"
00035 #include "MoochoPack_NLPAlgoClientInterface.hpp"
00036 #include "MoochoPack_NLPAlgoContainer.hpp"
00037 #include "MoochoPack_NLPAlgoState.hpp"
00038 #include "MoochoPack_MoochoTrackerSummaryStd.hpp"
00039 #include "MoochoPack_MoochoTrackerConsoleStd.hpp"
00040 #include "MoochoPack_MoochoTrackerStatsStd.hpp"
00041 #include "IterationPack_AlgorithmTrackerComposite.hpp"
00042 #include "NLPInterfacePack_NLPFirstOrder.hpp"
00043 #include "NLPInterfacePack_NLPDirect.hpp"
00044 #include "NLPInterfacePack_test_nlp_first_order.hpp"
00045 #include "NLPInterfacePack_test_nlp_direct.hpp"
00046 #include "OptionsFromStreamPack_OptionsFromStream.hpp"
00047 #include "StopWatchPack_stopwatch.hpp"
00048 #include "OptionsFromStreamPack_StringToIntMap.hpp"
00049 #include "OptionsFromStreamPack_StringToBool.hpp"
00050 #include "Teuchos_Workspace.hpp"
00051 #include "Teuchos_TestForException.hpp"
00052 #include "Teuchos_oblackholestream.hpp"
00053 #include "Teuchos_VerboseObject.hpp"
00054 #include "Teuchos_GlobalMPISession.hpp"
00055 #include "Teuchos_TimeMonitor.hpp"
00056 #include "Teuchos_Utils.hpp"
00057 
00058 namespace MoochoPack {
00059 
00060 // Initialization and algorithm configuration
00061 
00062 MoochoSolver::MoochoSolver(
00063   const std::string &options_file_name
00064   ,const std::string &extra_options_str
00065   )
00066   :reconfig_solver_(true)
00067   ,workspace_MB_(-1.0)
00068   ,obj_scale_(1.0)
00069   ,test_nlp_(true)
00070   ,print_algo_(true)
00071   ,algo_timing_(true)
00072   ,generate_stats_file_(false)
00073   ,print_opt_grp_not_accessed_(true)
00074   ,throw_exceptions_(false)
00075   ,do_console_outputting_(true)
00076   ,do_summary_outputting_(true)
00077   ,do_journal_outputting_(true)
00078   ,do_algo_outputting_(true)
00079   ,configuration_(MAMA_JAMA)
00080   ,output_to_black_hole_(OUTPUT_TO_BLACK_HOLE_DEFAULT)
00081   ,file_context_postfix_("")
00082   ,file_proc_postfix_("")
00083 {
00084   
00085   Teuchos::RefCountPtr<Teuchos::FancyOStream>
00086     defaultOut = Teuchos::VerboseObjectBase::getDefaultOStream();
00087   error_out_used_ = defaultOut;
00088 
00089   set_output_context("");
00090 
00091   commandLineOptionsFromStreamProcessor_.options_file_name_opt_name(
00092     "moocho-options-file");
00093   commandLineOptionsFromStreamProcessor_.options_file_name_opt_doc(
00094     "Set the name of the MOOCHO options file in the OptionsFromStream format."
00095     "  File is ignored if it does not exist!");
00096   commandLineOptionsFromStreamProcessor_.options_file_name(options_file_name);
00097 
00098   commandLineOptionsFromStreamProcessor_.extra_options_str_opt_name(
00099     "moocho-extra-options");
00100   commandLineOptionsFromStreamProcessor_.extra_options_str_opt_doc(
00101     "Extra MOOCHO options specified in the format"
00102     " \"OptGrp1{name1=val1,...,namen=valn}:OptGr2{name1=val1,...,namen=valn}:...\"");
00103   commandLineOptionsFromStreamProcessor_.extra_options_str(extra_options_str);
00104 
00105 }
00106 
00107 OptionsFromStreamPack::CommandLineOptionsFromStreamProcessor&
00108 MoochoSolver::commandLineOptionsFromStreamProcessor()
00109 {
00110   return commandLineOptionsFromStreamProcessor_;
00111 }
00112 
00113 const OptionsFromStreamPack::CommandLineOptionsFromStreamProcessor&
00114 MoochoSolver::commandLineOptionsFromStreamProcessor() const
00115 {
00116   return commandLineOptionsFromStreamProcessor_;
00117 }
00118 
00119 void MoochoSolver::setup_commandline_processor(
00120   Teuchos::CommandLineProcessor *clp
00121   )
00122 {
00123   commandLineOptionsFromStreamProcessor_.setup_commandline_processor(clp);
00124 }
00125 
00126 void MoochoSolver::set_output_context(
00127   const std::string    &file_context_postfix
00128   ,EOutputToBlackHole  output_to_black_hole
00129   ,const int           procRank_in
00130   ,const int           numProcs_in
00131   )
00132 {
00133 
00134   file_context_postfix_ = file_context_postfix;
00135 
00136   output_to_black_hole_ = output_to_black_hole;
00137   
00138   Teuchos::RefCountPtr<Teuchos::FancyOStream>
00139     defaultOut = Teuchos::VerboseObjectBase::getDefaultOStream();
00140   
00141   const int procRank
00142     = ( procRank_in >= 0 ? procRank_in : Teuchos::GlobalMPISession::getRank() );
00143   const int numProcs
00144     = ( numProcs_in > 0 ? numProcs_in : Teuchos::GlobalMPISession::getNProc() );
00145 
00146   if(output_to_black_hole_==OUTPUT_TO_BLACK_HOLE_DEFAULT) {
00147     if( numProcs > 1 && defaultOut->getOutputToRootOnly() >= 0 ) {
00148       output_to_black_hole_
00149         = ( defaultOut->getOutputToRootOnly()==procRank
00150             ? OUTPUT_TO_BLACK_HOLE_FALSE
00151             : OUTPUT_TO_BLACK_HOLE_TRUE
00152           );
00153     }
00154     else {
00155       output_to_black_hole_ = OUTPUT_TO_BLACK_HOLE_FALSE;
00156     }
00157   }
00158 
00159   if( numProcs > 1 ) {
00160     file_proc_postfix_ = Teuchos::Utils::getParallelExtension(procRank,numProcs);
00161   }
00162   else {
00163     file_proc_postfix_ = "";
00164   }
00165   
00166   summary_out_used_ = Teuchos::null;
00167   journal_out_used_ = Teuchos::null;
00168   algo_out_used_ = Teuchos::null;
00169   stats_out_used_ = Teuchos::null;
00170 
00171 }
00172 
00173 void MoochoSolver::set_nlp(const nlp_ptr_t& nlp)
00174 {
00175   nlp_ = nlp;
00176   reconfig_solver_ = true;
00177 }
00178   
00179 const MoochoSolver::nlp_ptr_t&
00180 MoochoSolver::get_nlp() const
00181 {
00182   return nlp_;
00183 }
00184 
00185 void MoochoSolver::set_track(const track_ptr_t& track)
00186 {
00187   track_ = track;
00188   solver_.set_track(Teuchos::null); // Force the track objects to be rebuilt and added!
00189 }
00190   
00191 const MoochoSolver::track_ptr_t&
00192 MoochoSolver::get_track() const
00193 {
00194   return track_;
00195 }
00196   
00197 void MoochoSolver::set_config( const config_ptr_t& config )
00198 {
00199   config_ = config;
00200   solver_.set_config(Teuchos::null); // Must unset the config object.
00201   reconfig_solver_ = true;
00202 }
00203 
00204 const MoochoSolver::config_ptr_t&
00205 MoochoSolver::get_config() const
00206 {
00207   return config_;
00208 }
00209 
00210 void MoochoSolver::set_options( const options_ptr_t& options )
00211 {
00212   options_ = options;                    // Must totally free all of the references we
00213   const config_ptr_t                     // have to the current options.  That includes
00214     &config = solver_.get_config();      // removing the options object for the configuration
00215   if(config.get())                       // object.
00216     config->set_options(Teuchos::null);  // ...
00217   options_used_ = options;
00218   commandLineOptionsFromStreamProcessor_.set_options(options);
00219   reconfig_solver_ = true;
00220 }
00221 
00222 const MoochoSolver::options_ptr_t&
00223 MoochoSolver::get_options() const
00224 {
00225   return options_;
00226 }
00227 
00228 void MoochoSolver::set_error_handling(
00229   bool                    throw_exceptions
00230   ,const ostream_ptr_t&   error_out
00231   )
00232 
00233 {
00234   if( error_out_.get() != NULL ) {
00235     if( error_out.get() == NULL )
00236       error_out_used_ = Teuchos::VerboseObjectBase::getDefaultOStream();
00237     else 
00238       error_out_used_ = error_out;
00239   }
00240   else if( error_out.get() != NULL ) {
00241     error_out_used_ = error_out;
00242   }
00243   throw_exceptions_ = throw_exceptions;
00244   error_out_       = error_out;
00245 }
00246 
00247 bool MoochoSolver::throw_exceptions() const
00248 {
00249   return throw_exceptions_;
00250 }
00251 
00252 const MoochoSolver::ostream_ptr_t&
00253 MoochoSolver::error_out() const
00254 {
00255   return error_out_;
00256 }
00257 
00258 void MoochoSolver::set_console_out( const ostream_ptr_t& console_out )
00259 {
00260   console_out_      = console_out;
00261   console_out_used_ = Teuchos::null;  // Remove every reference to this ostream object!
00262   solver_.set_track(Teuchos::null);
00263 }
00264 
00265 const MoochoSolver::ostream_ptr_t&
00266 MoochoSolver::get_console_out() const
00267 {
00268   return console_out_;
00269 }
00270 
00271 void MoochoSolver::set_summary_out( const ostream_ptr_t& summary_out )
00272 {
00273   summary_out_      = summary_out;
00274   summary_out_used_ = Teuchos::null;
00275   solver_.set_track(Teuchos::null);     // Remove every reference to this ostream object!
00276 }
00277   
00278 const MoochoSolver::ostream_ptr_t&
00279 MoochoSolver::get_summary_out() const
00280 {
00281   return summary_out_;
00282 }
00283 
00284 void MoochoSolver::set_journal_out( const ostream_ptr_t& journal_out )
00285 {
00286   journal_out_      = journal_out;
00287   journal_out_used_ = Teuchos::null;
00288   solver_.set_track(Teuchos::null);     // Remove every reference to this ostream object!
00289 }
00290   
00291 const MoochoSolver::ostream_ptr_t&
00292 MoochoSolver::get_journal_out() const
00293 {
00294   return journal_out_;
00295 }
00296 
00297 void MoochoSolver::set_algo_out( const ostream_ptr_t& algo_out )
00298 {
00299   algo_out_      = algo_out;
00300   algo_out_used_ = Teuchos::null;
00301 }
00302   
00303 const MoochoSolver::ostream_ptr_t&
00304 MoochoSolver::get_algo_out() const
00305 {
00306   return algo_out_;
00307 }
00308 
00309 // Solve the NLP
00310 
00311 MoochoSolver::ESolutionStatus MoochoSolver::solve_nlp() const
00312 {
00313   using std::endl;
00314   using std::setw;
00315   using StopWatchPack::stopwatch;
00316   using Teuchos::RefCountPtr;
00317 
00318   stopwatch                                  timer;
00319   bool                                       threw_exception = false;
00320   ESolutionStatus                            solve_return    = SOLVE_RETURN_EXCEPTION;
00321   NLPSolverClientInterface::EFindMinReturn   r_find_min      = NLPSolverClientInterface::SOLUTION_FOUND;
00322 
00323   try {
00324     
00325     update_solver();
00326 
00327     //
00328     // Direct any output from the NLP to the journal output file
00329     //
00330 
00331     EJournalOutputLevel olevel = solver_.journal_output_level();
00332     Teuchos::VerboseObjectTempState<NLP>
00333       nlpOutputTempState(nlp_,Teuchos::getFancyOStream(journal_out_used_),convertToVerbLevel(olevel));
00334 
00335     //
00336     // Scale the NLP objective function
00337     //
00338   
00339     nlp_->scale_f(obj_scale_);
00340 
00341     //
00342     // Test the nlp if needed
00343     //
00344     
00345     if(test_nlp_) {
00346       
00347       const char msg1[] = "\ntest_nlp = true: Testing the NLP! ...\n";
00348       if(do_console_outputting())
00349         *console_out_used_ << msg1;
00350       if(do_summary_outputting())
00351         *summary_out_used_ << msg1;
00352       if(do_journal_outputting())
00353         *journal_out_used_ << msg1;
00354       if(NLPFirstOrder* nlp_foi = dynamic_cast<NLPFirstOrder*>(nlp_.get())) {
00355         const char msg[] = "\nTesting the supported NLPFirstOrder interface ...\n";
00356         if(do_console_outputting())
00357           *console_out_used_ << msg;
00358         if(do_summary_outputting())
00359           *summary_out_used_ << msg;
00360         if(do_journal_outputting())
00361           *journal_out_used_ << msg;
00362         const bool
00363           result = NLPInterfacePack::test_nlp_first_order(
00364             nlp_foi,options_used_.get()
00365             ,do_journal_outputting() ? journal_out_used_.get() : NULL
00366             );
00367         if(!result) {
00368           const char msg[] = "\nNLPFirstOrder test failed (see journal file)!  exiting!\n";
00369           if(do_console_outputting())
00370             *console_out_used_ << msg;
00371           if(do_summary_outputting())
00372             *summary_out_used_ << msg;
00373           if(do_journal_outputting())
00374             *journal_out_used_ << msg;
00375           solve_return = SOLVE_RETURN_NLP_TEST_FAILED;
00376           return solve_return;
00377         }
00378       }
00379       else if(NLPDirect* nlp_fod = dynamic_cast<NLPDirect*>(nlp_.get())) {
00380         const char msg[] = "\nTesting the supported NLPDirect interface ...\n";
00381         if(do_console_outputting())
00382           *console_out_used_ << msg;
00383         if(do_summary_outputting())
00384           *summary_out_used_ << msg;
00385         if(do_journal_outputting())
00386           *journal_out_used_ << msg;
00387         const bool
00388           result = NLPInterfacePack::test_nlp_direct(
00389             nlp_fod,options_used_.get()
00390             ,do_journal_outputting() ? journal_out_used_.get() : NULL
00391             );
00392         if(!result) {
00393           const char msg[] = "\nNLPDirect test failed (see journal file)!  exiting!\n";
00394           if(do_console_outputting())
00395             *console_out_used_ << msg;
00396           if(do_summary_outputting())
00397             *summary_out_used_ << msg;
00398           if(do_journal_outputting())
00399             *journal_out_used_ << msg;
00400           solve_return = SOLVE_RETURN_NLP_TEST_FAILED;
00401           return solve_return;
00402         }
00403       }
00404       const char msg2[] = "\nSuccessful end of testing of the nlp\n";
00405       if(do_console_outputting())
00406         *console_out_used_ << msg2;
00407       if(do_summary_outputting())
00408         *summary_out_used_ << msg2;
00409       if(do_journal_outputting())
00410         *journal_out_used_ << msg2;
00411 
00412     }
00413     
00414     //
00415     // Solve the NLP
00416     //
00417     
00418     if(do_journal_outputting())
00419       *journal_out_used_
00420         << "\n************************************"
00421         << "\n*** MoochoSolver::solve_nlp()    ***"
00422         << "\n************************************\n" 
00423         << "\n*** Starting iterations ...\n\n";
00424     
00425     solver_.set_algo_timing(algo_timing_);
00426     timer.start();
00427     r_find_min = solver_.find_min();
00428     
00429     }
00430   catch(const std::exception& excpt) {
00431     std::ostringstream msg;
00432     msg << "\nMoochoSolver: Caught an std::exception of type "
00433         << typeid(excpt).name() << " described as : " << excpt.what() << endl;
00434     *error_out_used_  << msg.str();
00435     if(do_summary_outputting())
00436       *summary_out_used_ << msg.str();
00437     if(do_journal_outputting())
00438       *journal_out_used_ << msg.str();
00439     if(throw_exceptions_)
00440       throw;
00441     threw_exception = true;
00442   }
00443   catch(...) {
00444     std::ostringstream msg;
00445     msg << "\nMoochoSolver: Caught an unknown exception (i.e. ...)\n";
00446     *error_out_used_   << msg.str();
00447     if(do_summary_outputting())
00448       *summary_out_used_ << msg.str();
00449     if(do_journal_outputting())
00450       *journal_out_used_ << msg.str();
00451     if(throw_exceptions_)
00452       throw;
00453     threw_exception = true;
00454   }
00455   
00456   timer.stop();
00457   
00458   if(threw_exception) {
00459     if(do_summary_outputting())
00460       *summary_out_used_  << "\n\n****************************\n"
00461                 << "**** Threw an exception ****\n";
00462     solve_return = SOLVE_RETURN_EXCEPTION;
00463   }
00464   else {
00465     switch( r_find_min ) {
00466         case NLPSolverClientInterface::SOLUTION_FOUND: {
00467         if(do_summary_outputting())
00468           *summary_out_used_  << "\n\n************************\n"
00469                     << "**** Solution Found ****\n";
00470         *error_out_used_    << "Solution Found!\n";
00471         solve_return = SOLVE_RETURN_SOLVED;
00472         break;
00473       }
00474         case NLPSolverClientInterface::MAX_ITER_EXCEEDED: {
00475         if(do_summary_outputting())
00476           *summary_out_used_  << "\n\n**********************************************\n"
00477                     << "**** Maximun number of iteration exceeded ****\n";
00478         *error_out_used_    << "Maximun number of iteration exceeded!\n";
00479         solve_return = SOLVE_RETURN_MAX_ITER;
00480         break;
00481       }
00482         case NLPSolverClientInterface::MAX_RUN_TIME_EXCEEDED: {
00483         if(do_summary_outputting())
00484           *summary_out_used_  << "\n\n**********************************\n"
00485                     << "**** Maximun runtime exceeded ****\n";
00486         *error_out_used_    << "Maximun runtime exceeded!\n";
00487         solve_return = SOLVE_RETURN_MAX_RUN_TIME;
00488         break;
00489       }
00490         case NLPSolverClientInterface::ALGORITHMIC_ERROR: {
00491         if(do_summary_outputting())
00492           *summary_out_used_  << "\n\n*********************************************\n"
00493                     << "**** Some error occurred in the algorithm ****\n";
00494         *error_out_used_    << "Some algorithmic error occurred!\n";
00495         solve_return = SOLVE_RETURN_EXCEPTION;
00496         break;
00497       }
00498     }
00499   }
00500   
00501   if(do_summary_outputting()) {
00502     *summary_out_used_  << "\n  total time = " << timer.read() << " sec.\n";
00503     if( solver_.algo_timing() ) {
00504       Teuchos::TimeMonitor::format().setRowsBetweenLines(100);
00505       solver_.print_algorithm_times( *summary_out_used_ );
00506       *summary_out_used_ << "\n\n";
00507       Teuchos::TimeMonitor::summarize(*summary_out_used_);
00508     }
00509   }
00510   
00511   // Print workspace usage statistics
00512   if(do_summary_outputting())
00513     *summary_out_used_
00514       << "\n*** Statistics for automatic array workspace:"
00515       << "\nNumber of megabytes of preallocated workspace                = "
00516       << workspace_MB_
00517       << "\nNumber of allocations using preallocated workspace           = "
00518       << Teuchos::get_default_workspace_store()->num_static_allocations()
00519       << "\nNumber of dynamic allocations beyond preallocated workspace  = "
00520       << Teuchos::get_default_workspace_store()->num_dyn_allocations();
00521   
00522   // Print which options groups were not read
00523   if( do_algo_outputting() && print_opt_grp_not_accessed_ ) {
00524     *algo_out_used_
00525       <<  "\n***************************************************************\n"
00526       "Warning, the following options groups where not accessed.\n"
00527       "An options group may not be accessed if it is not looked for\n"
00528       "or if an \"optional\" options group was looked from and the user\n"
00529       "spelled it incorrectly:\n\n";
00530     if(options_used_.get())
00531       options_used_->print_unaccessed_options_groups(*algo_out_used_);
00532   }
00533 
00534   if(do_console_outputting())
00535     console_out_used_->flush();
00536   if(do_summary_outputting())
00537     summary_out_used_->flush();
00538   if(do_journal_outputting())
00539     journal_out_used_->flush();
00540   if(do_algo_outputting())
00541     algo_out_used_->flush();
00542   
00543   return solve_return;
00544   
00545 }
00546 
00547 // Get the underlying solver object
00548 
00549 NLPSolverClientInterface& MoochoSolver::get_solver()
00550 {
00551   update_solver();
00552   return solver_;
00553 }
00554 
00555 const NLPSolverClientInterface& MoochoSolver::get_solver() const
00556 {
00557   update_solver();
00558   return solver_;
00559 }
00560 
00561 // private
00562 
00563 Teuchos::RefCountPtr<std::ostream>
00564 MoochoSolver::generate_output_file(const std::string &fileNameBase) const
00565 {
00566   if( output_to_black_hole_ == OUTPUT_TO_BLACK_HOLE_TRUE )
00567     return Teuchos::rcp(new Teuchos::oblackholestream());
00568   std::string fileName = fileNameBase;
00569   if(file_context_postfix_.length())
00570     fileName += "." + file_context_postfix_;
00571   if(file_proc_postfix_.length())
00572     fileName += "." + file_proc_postfix_;
00573   fileName += ".out";
00574   return Teuchos::rcp(new std::ofstream(fileName.c_str()));
00575 }
00576 
00577 void MoochoSolver::generate_output_streams() const
00578 {
00579   if( do_console_outputting() && console_out_used_.get() == NULL ) {
00580     if( console_out_.get() != NULL )
00581       console_out_used_ = console_out_;
00582     else
00583       console_out_used_ = Teuchos::VerboseObjectBase::getDefaultOStream();
00584   }
00585   if( do_summary_outputting() && summary_out_used_.get()==NULL ) {
00586     if( summary_out_.get() == NULL )
00587       summary_out_used_ = generate_output_file("MoochoSummary");
00588     else
00589       summary_out_used_ = summary_out_;
00590   }
00591   if( do_journal_outputting() && journal_out_used_.get() == NULL ) {
00592     if( journal_out_.get() == NULL )
00593       journal_out_used_ = generate_output_file("MoochoJournal");
00594     else
00595       journal_out_used_ = journal_out_;
00596   }
00597   else {
00598     journal_out_used_ = Teuchos::rcp(new Teuchos::oblackholestream());
00599   }
00600   if( do_algo_outputting() && algo_out_used_.get() == NULL ) {
00601     if( algo_out_.get() == NULL )
00602       algo_out_used_ = generate_output_file("MoochoAlgo");
00603     else
00604       algo_out_used_ = algo_out_;
00605   }
00606   if( generate_stats_file_ && stats_out_used_.get() == NULL ) {
00607     stats_out_used_ = generate_output_file("MoochoStats");
00608   }
00609 }
00610 
00611 void MoochoSolver::update_solver() const
00612 {
00613 
00614   using std::endl;
00615   using std::setw;
00616   using StopWatchPack::stopwatch;
00617   using Teuchos::RefCountPtr;
00618   namespace ofsp = OptionsFromStreamPack;
00619   using ofsp::OptionsFromStream;
00620   using ofsp::StringToIntMap;
00621   using ofsp::StringToBool;
00622 
00624   // Validate the input
00625   //
00626   
00627   TEST_FOR_EXCEPTION(
00628     nlp_.get() == NULL, std::logic_error
00629     ,"MoochoSolver::update_solver() : Error, this->get_nlp().get() can not be NULL!" );
00630 
00631   
00632   //
00633   // Get the options (or lack of)
00634   //
00635 
00636   bool MoochoSolver_opt_grp_existed = true;
00637     
00638   if(reconfig_solver_) {
00639     
00640     if( options_used_.get() == NULL ) {
00641       if( options_.get() == NULL ) {
00642         options_used_ = commandLineOptionsFromStreamProcessor_.process_and_get_options();
00643       }
00644       else
00645         options_used_ = options_;
00646     }
00647     
00648     //
00649     // Read in some options for "MoochoSolver" if needed
00650     //
00651     
00652     if( options_used_.get() ) {
00653       
00654       options_used_->reset_unaccessed_options_groups();
00655       
00656       const std::string optgrp_name = "MoochoSolver";
00657       OptionsFromStream::options_group_t optgrp = options_used_->options_group( optgrp_name );
00658       if( OptionsFromStream::options_group_exists( optgrp ) ) {
00659         
00660         const int num_opt = 12;
00661         enum EOptions {
00662           WORKSPACE_MB
00663           ,OBJ_SCALE
00664           ,TEST_NLP
00665           ,CONSOLE_OUTPUTTING
00666           ,SUMMARY_OUTPUTTING
00667           ,JOURNAL_OUTPUTTING
00668           ,ALGO_OUTPUTTING
00669           ,PRINT_ALGO
00670           ,ALGO_TIMING
00671           ,GENERATE_STATS_FILE
00672           ,PRINT_OPT_GRP_NOT_ACCESSED
00673           ,CONFIGURATION
00674         };
00675         const char* SOptions[num_opt] = {
00676           "workspace_MB"
00677           ,"obj_scale"
00678           ,"test_nlp"
00679           ,"console_outputting"
00680           ,"summary_outputting"
00681           ,"journal_outputting"
00682           ,"algo_outputting"
00683           ,"print_algo"
00684           ,"algo_timing"
00685           ,"generate_stats_file"
00686           ,"print_opt_grp_not_accessed"
00687           ,"configuration"
00688         };
00689         
00690         const int num_config_opt = 2;
00691         
00692         const char* SConfigOptions[num_config_opt] = {
00693           "mama_jama"
00694           ,"interior_point"
00695         };
00696         
00697         StringToIntMap  config_map( optgrp_name, num_config_opt, SConfigOptions );
00698         
00699         StringToIntMap  opt_map( optgrp_name, num_opt, SOptions );
00700         
00701         OptionsFromStream::options_group_t::const_iterator itr = optgrp.begin();
00702         for( ; itr != optgrp.end(); ++itr ) {
00703           switch( (EOptions)opt_map( ofsp::option_name(itr) ) ) {
00704             case WORKSPACE_MB:
00705               workspace_MB_ = ::atof( ofsp::option_value(itr).c_str() );
00706               break;
00707             case OBJ_SCALE:
00708               obj_scale_ = ::atof( ofsp::option_value(itr).c_str() );
00709               break;
00710             case TEST_NLP:
00711               test_nlp_ = StringToBool( "test_nlp", ofsp::option_value(itr).c_str() );
00712               break;
00713             case CONSOLE_OUTPUTTING:
00714               do_console_outputting_ = StringToBool( "console_outputting", ofsp::option_value(itr).c_str() );
00715               break;
00716             case SUMMARY_OUTPUTTING:
00717               do_summary_outputting_ = StringToBool( "summary_outputting", ofsp::option_value(itr).c_str() );
00718               break;
00719             case JOURNAL_OUTPUTTING:
00720               do_journal_outputting_ = StringToBool( "journal_outputting", ofsp::option_value(itr).c_str() );
00721               break;
00722             case ALGO_OUTPUTTING:
00723               do_algo_outputting_ = StringToBool( "algo_outputting", ofsp::option_value(itr).c_str() );
00724               break;
00725             case PRINT_ALGO:
00726               print_algo_ = StringToBool( "print_algo", ofsp::option_value(itr).c_str() );
00727               break;
00728             case ALGO_TIMING:
00729               algo_timing_ = StringToBool( "algo_timing", ofsp::option_value(itr).c_str() );
00730               break;
00731             case GENERATE_STATS_FILE:
00732               generate_stats_file_ = StringToBool( "generate_stats_file", ofsp::option_value(itr).c_str() );
00733               break;
00734             case PRINT_OPT_GRP_NOT_ACCESSED:
00735               print_opt_grp_not_accessed_ = StringToBool( "algo_timing", ofsp::option_value(itr).c_str() );
00736               break;
00737             case CONFIGURATION:
00738               configuration_ = config_map( ofsp::option_value(itr).c_str() );
00739               break;
00740             default:
00741               TEST_FOR_EXCEPT(true);  // this would be a local programming error only.
00742           }
00743         }
00744       }
00745       else {
00746         MoochoSolver_opt_grp_existed = false;
00747       }
00748 
00749     }
00750     
00751   }
00752   
00753   //
00754   // Get the output streams if needed
00755   //
00756 
00757   generate_output_streams();  
00758   
00759   if( do_algo_outputting() && !MoochoSolver_opt_grp_existed )
00760     *algo_out_used_
00761       << "\nWarning!  The options group \'MoochoSolver\' was not found.\n"
00762       "Using a default set of options ...\n";
00763 
00764   //
00765   // Configure the algorithm
00766   //
00767     
00768   if(reconfig_solver_) {
00769     
00770     //
00771     // Print the headers for the output files
00772     //
00773       
00774     int prec = 8;
00775     if(do_summary_outputting())
00776       summary_out_used_->precision(prec);
00777     if(do_journal_outputting())
00778       *journal_out_used_ << std::setprecision(prec) << std::scientific;
00779 
00780     if(do_algo_outputting())
00781       *algo_out_used_
00782         << "\n********************************************************************"
00783         << "\n*** Algorithm information output                                 ***"
00784         << "\n***                                                              ***"
00785         << "\n*** Below, information about how the the MOOCHO algorithm is     ***"
00786         << "\n*** setup is given and is followed by detailed printouts of the  ***"
00787         << "\n*** contents of the algorithm state object (i.e. iteration       ***"
00788         << "\n*** quantities) and the algorithm description printout           ***"
00789         << "\n*** (if the option MoochoSolver::print_algo = true is set).      ***"
00790         << "\n********************************************************************\n";
00791     if(do_summary_outputting())
00792       *summary_out_used_
00793         << "\n********************************************************************"
00794         << "\n*** Algorithm iteration summary output                           ***"
00795         << "\n***                                                              ***"
00796         << "\n*** Below, a summary table of the SQP iterations is given as     ***"
00797         << "\n*** well as a table of the CPU times for each step (if the       ***"
00798         << "\n*** option MoochoSolver::algo_timing = true is set).             ***"
00799         << "\n********************************************************************\n";
00800     if(do_journal_outputting())
00801       *journal_out_used_
00802         << "\n********************************************************************"
00803         << "\n*** Algorithm iteration detailed journal output                  ***"
00804         << "\n***                                                              ***"
00805         << "\n*** Below, detailed information about the SQP algorithm is given ***"
00806         << "\n*** while it is running.  The amount of information that is      ***"
00807         << "\n*** produced can be specified using the option                   ***"
00808         << "\n*** NLPSolverClientInterface::journal_output_level (the default ***"
00809         << "\n*** is PRINT_NOTHING and produces no output                      ***"
00810         << "\n********************************************************************\n";
00811     
00812     // Echo options.
00813     if(do_summary_outputting()) {
00814       *summary_out_used_ << "\n*** Echoing input options ...\n";
00815       if(options_used_.get())
00816         options_used_->print_options( *summary_out_used_ );
00817       summary_out_used_->flush();
00818     }
00819     if(do_algo_outputting()) {
00820       *algo_out_used_ << "\n*** Echoing input options ...\n";
00821       if(options_used_.get())
00822         options_used_->print_options( *algo_out_used_ );
00823       algo_out_used_->flush();
00824     }
00825     if(do_journal_outputting()) {
00826       *journal_out_used_ << "\n*** Echoing input options ...\n";
00827       if(options_used_.get())
00828         options_used_->print_options( *journal_out_used_ );
00829       journal_out_used_->flush();
00830     }
00831       
00832     //
00833     // Allocate the workspace
00834     //
00835       
00836     nlp_->set_options(options_used_);
00837     nlp_->initialize();
00838     const int default_ws_scale = 10;
00839     if( workspace_MB_ < 0.0 ) {
00840       workspace_MB_ = nlp_->n() * default_ws_scale * 1e-6 * sizeof(value_type);
00841       if(do_algo_outputting())
00842         *algo_out_used_
00843           << "\nworkspace_MB < 0.0:\n"
00844           << "Setting workspace_MB = n * default_ws_scale * 1e-6 * sizeof(value_type) = "
00845           << nlp_->n() << " * " << default_ws_scale << " * 1e-6 * " << sizeof(value_type)
00846           << " = " << workspace_MB_ << " MB\n";
00847     }
00848     if(do_summary_outputting())
00849       *summary_out_used_
00850         << "\nAllocating workspace_MB = " << workspace_MB_ << " megabytes of temporary "
00851         "workspace for automatic arrays only ...\n";
00852     Teuchos::set_default_workspace_store(
00853       Teuchos::rcp(new Teuchos::WorkspaceStoreInitializeable(static_cast<size_t>(1e+6*workspace_MB_)))
00854       );
00855     
00856     //
00857     // Reconfigure the algorithm
00858     //
00859       
00860     // Get and set up the configuration object
00861     config_ptr_t _config;
00862     if(config_.get() == NULL) {
00863       if (configuration_ == (EConfigOptions) INTERIOR_POINT) {
00864           _config = Teuchos::rcp(new NLPAlgoConfigIP());
00865             }
00866       else {
00867           _config = Teuchos::rcp(new NLPAlgoConfigMamaJama());
00868       }
00869         }
00870     else
00871       _config = config_;
00872     _config->set_options( options_used_ );
00873       
00874     if( do_summary_outputting() || do_journal_outputting() || do_algo_outputting() ) {
00875       std::ostringstream msg;
00876       msg << "\n*** Setting up to run MOOCHO on the NLP using a "
00877         << "configuration object of type \'" << typeid(*_config).name() << "\' ...\n";
00878       if(do_summary_outputting())
00879         *summary_out_used_ << msg.str();
00880       if(do_journal_outputting())
00881         *journal_out_used_ << msg.str();
00882       if(do_algo_outputting())
00883         *algo_out_used_ << msg.str();
00884     }
00885       
00886     // Set up the solver
00887       
00888     solver_.set_nlp(nlp_);           // Set the NLP object
00889     solver_.set_config(_config);     // Set the configuration object
00890       
00891     // Set the client interface options
00892     if(options_used_.get()) {
00893       NLPSolverClientInterfaceSetOptions
00894         solver_options_setter( &solver_ );
00895       solver_options_setter.set_options( *options_used_ );
00896     }
00897     
00898     reconfig_solver_ = false;
00899 
00900     //
00901     // Set up the track objects
00902     //
00903     
00904     RefCountPtr<AlgorithmTrackerComposite>
00905       composite_track = Teuchos::rcp(new AlgorithmTrackerComposite(journal_out_used_));
00906     if(do_console_outputting())
00907       composite_track->tracks().push_back(
00908         Teuchos::rcp(new MoochoTrackerConsoleStd(console_out_used_,journal_out_used_)) );
00909     if(do_summary_outputting())
00910       composite_track->tracks().push_back(
00911         Teuchos::rcp(new MoochoTrackerSummaryStd(summary_out_used_,journal_out_used_)) );
00912     if(stats_out_used_.get()) {
00913       composite_track->tracks().push_back(
00914         Teuchos::rcp(new MoochoTrackerStatsStd(stats_out_used_,stats_out_used_)) );
00915     }
00916     if( track_.get() ) {
00917       track_->set_journal_out(journal_out_used_);
00918       composite_track->tracks().push_back( track_ );
00919     }
00920     solver_.set_track( composite_track );
00921     
00922     //
00923     // Configure and print the algorithm if needed
00924     //
00925     
00926     solver_.configure_algorithm(algo_out_used_.get());
00927     if( do_algo_outputting() && print_algo_ )
00928       solver_.print_algorithm(*algo_out_used_);
00929 
00930   }
00931   
00932 }
00933 
00934 } // end namespace MoochoPack

Generated on Thu Sep 18 12:34:28 2008 for MoochoPack : Framework for Large-Scale Optimization Algorithms by doxygen 1.3.9.1