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