TSFNOXSolver.C
Go to the documentation of this file.
00001 // $Id$ 
00002 // $Source$ 
00003 
00004 //@HEADER
00005 // ************************************************************************
00006 // 
00007 //            NOX: An Object-Oriented Nonlinear Solver Package
00008 //                 Copyright (2002) Sandia Corporation
00009 // 
00010 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00011 // license for use of this work by or on behalf of the U.S. Government.
00012 // 
00013 // This library is free software; you can redistribute it and/or modify
00014 // it under the terms of the GNU Lesser General Public License as
00015 // published by the Free Software Foundation; either version 2.1 of the
00016 // License, or (at your option) any later version.
00017 //  
00018 // This library is distributed in the hope that it will be useful, but
00019 // WITHOUT ANY WARRANTY; without even the implied warranty of
00020 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00021 // Lesser General Public License for more details.
00022 //                                                                                 
00023 // You should have received a copy of the GNU Lesser General Public
00024 // License along with this library; if not, write to the Free Software
00025 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00026 // USA                                                                                
00027 // Questions? Contact Tammy Kolda (tgkolda@sandia.gov) or Roger Pawlowski
00028 // (rppawlo@sandia.gov), Sandia National Laboratories.
00029 // 
00030 // ************************************************************************
00031 //@HEADER
00032 
00033 #include "TSFNOXSolver.H"         
00034 #include "NOX_StatusTest_SafeCombo.H"         
00035 #include "NOX.H"         
00036 //#include "NOX_Parameter_Teuchos2NOX.H"         
00037 #include "TSFLinearSolverBuilder.hpp"
00038 #include "Teuchos_Time.hpp"
00039 #include "Teuchos_TimeMonitor.hpp"
00040 #include "SundanceOut.hpp"
00041 #include "SundanceTabs.hpp"
00042 #include "SundanceExceptions.hpp"
00043 #ifndef HAVE_TEUCHOS_EXPLICIT_INSTANTIATION
00044 #include "TSFVectorImpl.hpp"
00045 #include "TSFLinearOperatorImpl.hpp"
00046 #endif
00047 
00048 
00049 using namespace NOX;
00050 using namespace NOX::TSF;
00051 using namespace Teuchos;
00052 using namespace TSFExtended;
00053 
00054 
00055 static Time& noxSolverTimer() 
00056 {
00057   static RCP<Time> rtn 
00058     = TimeMonitor::getNewTimer("NOX solve"); 
00059   return *rtn;
00060 }
00061 
00062 NOXSolver::NOXSolver(const ParameterList& params)
00063   : linSolver_(),
00064     statusTest_(),
00065     params_(),
00066     printParams_()
00067 {
00068   TEST_FOR_EXCEPTION(!params.isSublist("NOX Solver"), runtime_error,
00069                      "did not find NOX Solver sublist in " << params);
00070   
00071   params_ = params.sublist("NOX Solver");
00072   /* NOX wants to have the process ID in a parameter list???? */
00073   params_.sublist("Printing").set("MyPID", MPIComm::world().getRank());
00074 
00075   if (params_.isSublist("Status Test"))
00076     {
00077       statusTest_ = StatusTestBuilder::makeStatusTest(params_);
00078     }
00079   else
00080     {
00081       RCP<StatusTest::Generic> A = rcp(new StatusTest::NormF(1.0e-12));
00082       RCP<StatusTest::Generic> B = rcp(new StatusTest::MaxIters(20));
00083       statusTest_ = 
00084         rcp(new StatusTest::SafeCombo(StatusTest::SafeCombo::OR, A, B));
00085     }
00086   
00087   if (params_.isSublist("Linear Solver"))
00088     {
00089       linSolver_ = LinearSolverBuilder::createSolver(params_);
00090     }
00091   else
00092   {
00093     TEST_FOR_EXCEPTION(!params_.isSublist("Linear Solver"),
00094       RuntimeError, "no linear solver specified in NOX parameters");
00095   }
00096   
00097   if (params_.isSublist("Printing"))
00098     {
00099       printParams_ = params_.sublist("Printing");
00100     }
00101   
00102   TEST_FOR_EXCEPTION(linSolver_.ptr().get()==0, runtime_error,
00103                      "null linear solver object in NOXSolver ctor");
00104 
00105   TEST_FOR_EXCEPTION(statusTest_.get()==0, runtime_error,
00106                      "null status test object in NOXSolver ctor");
00107 
00108 }
00109 
00110 NOXSolver::NOXSolver(const ParameterList& nonlinParams,
00111       const LinearSolver<double>& linSolver)
00112   : linSolver_(linSolver),
00113     statusTest_(),
00114     params_(),
00115     printParams_()
00116 {
00117   Tabs tab(0);
00118   TEST_FOR_EXCEPTION(!nonlinParams.isSublist("NOX Solver"), runtime_error,
00119                      "did not find NOX Solver sublist in " << nonlinParams);
00120   
00121   params_ = nonlinParams.sublist("NOX Solver");
00122   /* NOX wants to have the process ID in a parameter list???? */
00123   params_.sublist("Printing").set("MyPID", MPIComm::world().getRank());
00124 
00125   if (params_.isSublist("Status Test"))
00126     {
00127       statusTest_ = StatusTestBuilder::makeStatusTest(params_);
00128     }
00129   else
00130     {
00131       RCP<StatusTest::Generic> A = rcp(new StatusTest::NormF(1.0e-12));
00132       RCP<StatusTest::Generic> B = rcp(new StatusTest::MaxIters(20));
00133       statusTest_ = 
00134         rcp(new StatusTest::SafeCombo(StatusTest::SafeCombo::OR, A, B));
00135     }
00136   
00137   if (params_.isSublist("Linear Solver"))
00138     {
00139       Out::root() << tab << "WARNING: linear solver in NOX parameter list "
00140         "will be overridden by alternate solver" << std::endl;
00141     }
00142   
00143   if (params_.isSublist("Printing"))
00144     {
00145       printParams_ = params_.sublist("Printing");
00146     }
00147   
00148   TEST_FOR_EXCEPTION(linSolver_.ptr().get()==0, runtime_error,
00149                      "null linear solver object in NOXSolver ctor");
00150 
00151   TEST_FOR_EXCEPTION(statusTest_.get()==0, runtime_error,
00152                      "null status test object in NOXSolver ctor");
00153 
00154 }
00155 
00156 
00157 
00158 
00159 NOX::StatusTest::StatusType 
00160 NOXSolver::solve(const NonlinearOperator<double>& F, 
00161                  TSFExtended::Vector<double>& solnVec) const 
00162 {
00163   TimeMonitor timer(noxSolverTimer());
00164 
00165   Vector<double> x0 = F.getInitialGuess();
00166   RCP<NOX::TSF::Group> grp = rcp(new NOX::TSF::Group(x0, F, linSolver_));
00167   RCP<Teuchos::ParameterList> noxParams 
00168     = Teuchos::rcp(&params_, false);
00169   RCP<NOX::Solver::Generic> solver 
00170     = NOX::Solver::buildSolver(grp, statusTest_, noxParams);
00171 
00172   NOX::StatusTest::StatusType rtn = solver->solve();
00173 
00174   const NOX::TSF::Group* solnGrp 
00175     = dynamic_cast<const NOX::TSF::Group*>(&(solver->getSolutionGroup()));
00176 
00177   TEST_FOR_EXCEPTION(solnGrp==0, runtime_error,
00178                      "Solution group could not be cast to NOX::TSF::Group");
00179 
00180   const NOX::TSF::Vector* x 
00181     = dynamic_cast<const NOX::TSF::Vector*>(&(solnGrp->getX()));
00182 
00183   TEST_FOR_EXCEPTION(x==0, runtime_error,
00184     "Solution vector could not be cast to NOX::TSF::Vector");
00185   
00186   solnVec = x->getTSFVector();
00187 
00188   return rtn;
00189 }

Site Contact