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

Generated on Tue Jul 13 09:30:53 2010 for MOOCHO (Single Doxygen Collection) by  doxygen 1.4.7