00001 #include "EpetraModelEval2DSim.hpp"
00002 #include "EpetraModelEval4DOpt.hpp"
00003 #include "Thyra_EpetraModelEvaluator.hpp"
00004 #include "Thyra_DefaultModelEvaluatorWithSolveFactory.hpp"
00005 #include "Thyra_AmesosLinearOpWithSolveFactory.hpp"
00006 #include "Thyra_DampenedNewtonNonlinearSolver.hpp"
00007 #include "Teuchos_VerboseObject.hpp"
00008 #include "Teuchos_CommandLineProcessor.hpp"
00009 #include "Teuchos_StandardCatchMacros.hpp"
00010
00011 int main( int argc, char* argv[] )
00012 {
00013
00014 using Teuchos::CommandLineProcessor;
00015 typedef Teuchos::RefCountPtr<Thyra::VectorBase<double> > VectorPtr;
00016
00017 bool success = true;
00018
00019 try {
00020
00021
00022
00023
00024
00025 CommandLineProcessor clp;
00026 clp.throwExceptions(false);
00027 clp.addOutputSetupOptions(true);
00028
00029 clp.setDocString(
00030 "This example program solves a simple 2 x 2 set of nonlinear equations using a simple\n"
00031 "dampened Newton method.\n\n"
00032
00033 "The equations that are solved are:\n\n"
00034
00035 " f[0] = x[0] + x[1]*x[1] - p[0];\n"
00036 " f[1] = d * ( x[0]*x[0] - x[1] - p[1] );\n\n"
00037
00038 "The Jacobian for these equations is nonsingular for every point except x=(-0.5,0.5)\n"
00039 "and x=(0.5,-0.5) You can cause the Jacobian to be singular at the solution by setting\n"
00040 "p[0]=x[0]+x[1]*x[1] and p[1] = x[0]*x[0]-x[1] for these values of x.\n\n"
00041
00042 "The equations are solved using a simple dampended Newton method that uses a Armijo\n"
00043 "line search which is implemented in the general class Thyra::DampenedNewtonNonlinearsolver\n"
00044 "You can get different levels of detail about the Newton method by adjustingthe command-line\n"
00045 "option \"verb-level\" (see above)\n"
00046 );
00047
00048 double d = 10.0;
00049 double p0 = 2.0;
00050 double p1 = 0.0;
00051 double x00 = 0.0;
00052 double x01 = 1.0;
00053
00054 const int numVerbLevels = 6;
00055 const Teuchos::EVerbosityLevel verbLevelValues[numVerbLevels]
00056 = { Teuchos::VERB_DEFAULT, Teuchos::VERB_NONE, Teuchos::VERB_LOW
00057 ,Teuchos::VERB_MEDIUM, Teuchos::VERB_HIGH, Teuchos::VERB_EXTREME };
00058 const char* verbLevelNames[numVerbLevels]
00059 = {"default","none","low","medium","high","extreme"};
00060 Teuchos::EVerbosityLevel verbLevel = Teuchos::VERB_DEFAULT;
00061
00062 double tol = 1e-10;
00063 int maxIters = 100;
00064
00065 bool use4DOpt = false;
00066 bool externalFactory = false;
00067
00068 bool showSetInvalidArg = false;
00069 bool showGetInvalidArg = false;
00070
00071 clp.setOption( "d", &d, "Model constant d" );
00072 clp.setOption( "p0", &p0, "Model constant p[0]" );
00073 clp.setOption( "p1", &p1, "Model constant p[1]" );
00074 clp.setOption( "x00", &x00, "Initial guess for x[0]" );
00075 clp.setOption( "x01", &x01, "Initial guess for x[1]" );
00076 clp.setOption( "verb-level", &verbLevel, numVerbLevels, verbLevelValues, verbLevelNames, "Verbosity level" );
00077 clp.setOption( "tol", &tol, "Nonlinear solve tolerance" );
00078 clp.setOption( "max-iters", &maxIters, "Maximum number of nonlinear iterations" );
00079 clp.setOption( "use-4D-opt", "use-2D-sim", &use4DOpt
00080 ,"Determines if the EpetraModelEval4DOpt or EpetraModelEval2DSim subclasses are used" );
00081 clp.setOption( "external-lowsf", "internal-lowsf", &externalFactory
00082 ,"Determines of the Thyra::LinearOpWithSolveFactory is used externally or internally to the Thyra::EpetraModelEvaluator object" );
00083 clp.setOption( "show-set-invalid-arg", "no-show-set-invalid-arg", &showSetInvalidArg
00084 ,"Determines if an attempt is made to set an invalid/unsupported ModelEvaluator input argument" );
00085 clp.setOption( "show-get-invalid-arg", "no-show-get-invalid-arg", &showGetInvalidArg
00086 ,"Determines if an attempt is made to get an invalid/unsupported ModelEvaluator output argument (2DSim only)" );
00087
00088 CommandLineProcessor::EParseCommandLineReturn
00089 parse_return = clp.parse(argc,argv,&std::cerr);
00090
00091 if( parse_return != CommandLineProcessor::PARSE_SUCCESSFUL )
00092 return parse_return;
00093
00094 Teuchos::RefCountPtr<Teuchos::FancyOStream>
00095 out = Teuchos::VerboseObjectBase::getDefaultOStream();
00096
00097 *out << "\nCreating the nonlinear equations object ...\n";
00098
00099 Teuchos::RefCountPtr<EpetraExt::ModelEvaluator> epetraModel;
00100 if(use4DOpt) {
00101 epetraModel = rcp(new EpetraModelEval4DOpt(0.0,0.0,p0,p1,d,x00,x01,p0,p1));
00102 }
00103 else {
00104 epetraModel = rcp(new EpetraModelEval2DSim(d,p0,p1,x00,x01,showGetInvalidArg));
00105 }
00106
00107 Teuchos::RefCountPtr<Thyra::LinearOpWithSolveFactoryBase<double> >
00108 lowsFactory = rcp(new Thyra::AmesosLinearOpWithSolveFactory());
00109
00110 Teuchos::RefCountPtr<Thyra::EpetraModelEvaluator>
00111 epetraThyraModel = rcp(new Thyra::EpetraModelEvaluator());
00112
00113 Teuchos::RefCountPtr<Thyra::ModelEvaluator<double> > thyraModel;
00114 if(externalFactory) {
00115 epetraThyraModel->initialize(epetraModel,Teuchos::null);
00116 thyraModel = Teuchos::rcp(
00117 new Thyra::DefaultModelEvaluatorWithSolveFactory<double>(
00118 epetraThyraModel
00119 ,lowsFactory
00120 )
00121 );
00122 }
00123 else {
00124 epetraThyraModel->initialize(epetraModel,lowsFactory);
00125 thyraModel = epetraThyraModel;
00126 }
00127
00128 if( showSetInvalidArg ) {
00129 *out << "\nAttempting to set an invalid input argument that throws an exception ...\n\n";
00130 Thyra::ModelEvaluatorBase::InArgs<double> inArgs = thyraModel->createInArgs();
00131 inArgs.set_x_dot(createMember(thyraModel->get_x_space()));
00132 }
00133
00134 *out << "\nCreating the nonlinear solver and solving the equations ...\n\n";
00135
00136 Thyra::DampenedNewtonNonlinearSolver<double> newtonSolver;
00137 newtonSolver.setVerbLevel(verbLevel);
00138
00139 VectorPtr x = createMember(thyraModel->get_x_space());
00140 V_V( &*x, *thyraModel->getNominalValues().get_x() );
00141
00142 Thyra::SolveCriteria<double> solveCriteria;
00143 solveCriteria.solveMeasureType.set(Thyra::SOLVE_MEASURE_NORM_RESIDUAL,Thyra::SOLVE_MEASURE_NORM_RHS);
00144 solveCriteria.requestedTol = tol;
00145 solveCriteria.extraParameters = Teuchos::rcp(new Teuchos::ParameterList("Nonlinear Solve"));
00146 solveCriteria.extraParameters->set("Max Iters",int(maxIters));
00147
00148 newtonSolver.setModel(thyraModel);
00149 Thyra::SolveStatus<double>
00150 solveStatus = newtonSolver.solve(&*x,&solveCriteria);
00151
00152 *out << "\nNonlinear solver return status:\n";
00153 if(1) {
00154 Teuchos::OSTab tab(out);
00155 *out << solveStatus;
00156 }
00157 *out << "\nFinal solution for x=\n" << *x;
00158
00159 }
00160 TEUCHOS_STANDARD_CATCH_STATEMENTS(true,std::cerr,success)
00161
00162 return success ? 0 : 1;
00163 }