basicExample/cxx_main.cpp

Go to the documentation of this file.
00001 //@HEADER
00002 
00003 // ***********************************************************************
00004 //
00005 //                     Rythmos Package
00006 //                 Copyright (2006) Sandia Corporation
00007 //
00008 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00009 // license for use of this work by or on behalf of the U.S. Government.
00010 //
00011 // This library is free software; you can redistribute it and/or modify
00012 // it under the terms of the GNU Lesser General Public License as
00013 // published by the Free Software Foundation; either version 2.1 of the
00014 // License, or (at your option) any later version.
00015 //
00016 // This library is distributed in the hope that it will be useful, but
00017 // WITHOUT ANY WARRANTY; without even the implied warranty of
00018 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00019 // Lesser General Public License for more details.
00020 //
00021 // You should have received a copy of the GNU Lesser General Public
00022 // License along with this library; if not, write to the Free Software
00023 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00024 // USA
00025 // Questions? Contact Todd S. Coffey (tscoffe@sandia.gov)
00026 //
00027 // ***********************************************************************
00028 //@HEADER 
00029 
00030 #include "Epetra_Map.h"
00031 #include "Epetra_Vector.h"
00032 #include "Epetra_Version.h"
00033 #ifdef HAVE_MPI
00034 #include "Epetra_MpiComm.h"
00035 #include "mpi.h"
00036 #else
00037 #include "Epetra_SerialComm.h"
00038 #endif // HAVE_MPI
00039 
00040 #include "ExampleApplication.hpp"
00041 
00042 // Includes for Rythmos:
00043 #include "Rythmos_ConfigDefs.h"
00044 //#include "ExampleApplicationRythmosInterface.hpp"
00045 #include "Rythmos_ForwardEulerStepper.hpp"
00046 #include "Rythmos_BackwardEulerStepper.hpp"
00047 #include "Rythmos_ExplicitRKStepper.hpp"
00048 #include "Rythmos_ImplicitBDFStepper.hpp"
00049 
00050 // Includes for Thyra:
00051 #include "Thyra_EpetraThyraWrappers.hpp"
00052 #include "Thyra_EpetraLinearOp.hpp"
00053 #include "Thyra_EpetraModelEvaluator.hpp"
00054 #include "Thyra_LinearNonlinearSolver.hpp"
00055 #include "Thyra_TimeStepNewtonNonlinearSolver.hpp"
00056 #include "Thyra_TestingTools.hpp"
00057 
00058 // Includes for Stratimikos:
00059 #ifdef HAVE_RYTHMOS_STRATIMIKOS
00060 #  include "Thyra_DefaultRealLinearSolverBuilder.hpp"
00061 #endif
00062 
00063 #include <string>
00064 
00065 // Includes for Teuchos:
00066 #include "Teuchos_RefCountPtr.hpp"
00067 #include "Teuchos_ParameterList.hpp"
00068 #include "Teuchos_CommandLineProcessor.hpp"
00069 #include "Teuchos_FancyOStream.hpp"
00070 #include "Teuchos_GlobalMPISession.hpp"
00071 #include "Teuchos_VerboseObject.hpp"
00072 #include "Teuchos_StandardCatchMacros.hpp"
00073 
00074 enum EMethod { METHOD_FE, METHOD_BE, METHOD_ERK, METHOD_BDF };
00075 enum EStepMethod { FIXED_STEP, VARIABLE_STEP };
00076 
00077 int main(int argc, char *argv[])
00078 {
00079   bool verbose = false; // verbosity level.
00080   bool result, success = true; // determine if the run was successfull
00081 
00082   Teuchos::GlobalMPISession mpiSession(&argc,&argv);
00083 
00084   Teuchos::RefCountPtr<Teuchos::FancyOStream>
00085     out = Teuchos::VerboseObjectBase::getDefaultOStream();
00086 
00087 #ifdef HAVE_MPI
00088   MPI_Comm mpiComm = MPI_COMM_WORLD;
00089 #endif // HAVE_MPI
00090 
00091   try { // catch exceptions
00092 
00093     double lambda_min = -0.9;   // min ODE coefficient
00094     double lambda_max = -0.01;  // max ODE coefficient
00095     double coeff_s = 0.0;  // Default is no forcing term
00096     std::string lambda_fit = "linear"; // Lambda model
00097     int numElements = 1; // number of elements in vector
00098     double x0 = 10.0; // ODE initial condition
00099     double finalTime = 1.0; // ODE final time
00100     int N = 10;  // number of steps to take
00101     const int num_methods = 4;
00102     const EMethod method_values[] = { METHOD_FE, METHOD_BE, METHOD_ERK, METHOD_BDF };
00103     const char * method_names[] = { "FE", "BE", "ERK", "BDF" };
00104     EMethod method_val = METHOD_ERK;
00105     const int num_step_methods = 2;
00106     const EStepMethod step_method_values[] = { FIXED_STEP, VARIABLE_STEP };
00107     const char * step_method_names[] = { "fixed", "variable" };
00108     EStepMethod step_method_val = FIXED_STEP;
00109     double maxError = 1e-6;
00110     bool version = false;  // display version information 
00111     double reltol = 1.0e-2;
00112     double abstol = 1.0e-4;
00113     int maxOrder = 5;
00114 #ifdef Rythmos_DEBUG
00115     int debugLevel = 2; // debugLevel is used when Rythmos_DEBUG ifdef is set.
00116 #endif // Rythmos_DEBUG
00117 
00118     // Parse the command-line options:
00119     Teuchos::CommandLineProcessor  clp(false); // Don't throw exceptions
00120     clp.addOutputSetupOptions(true);
00121 #ifdef HAVE_RYTHMOS_STRATIMIKOS
00122     Thyra::DefaultRealLinearSolverBuilder lowsfCreator;
00123     lowsfCreator.setupCLP(&clp);
00124 #endif
00125     clp.setOption( "x0", &x0, "Constant ODE initial condition." );
00126     clp.setOption( "T", &finalTime, "Final time for simulation." );
00127     clp.setOption( "lambda_min", &lambda_min, "Lower bound for ODE coefficient");
00128     clp.setOption( "lambda_max", &lambda_max, "Upper bound for ODE coefficient");
00129     clp.setOption( "lambda_fit", &lambda_fit, "Lambda model:  random, linear");
00130     clp.setOption( "force_coeff", &coeff_s, "Forcing term coefficient");
00131     clp.setOption( "numelements", &numElements, "Problem size");
00132     clp.setOption( "method", &method_val, num_methods, method_values, method_names, "Integration method" );
00133     clp.setOption( "stepmethod", &step_method_val, num_step_methods, step_method_values, step_method_names, "Stepping method" );
00134     clp.setOption( "numsteps", &N, "Number of integration steps to take" );
00135     clp.setOption( "maxerror", &maxError, "Maximum error" );
00136     clp.setOption( "verbose", "quiet", &verbose, "Set if output is printed or not" );
00137     clp.setOption( "version", "run", &version, "Version of this code" );
00138     clp.setOption( "reltol", &reltol, "Relative Error Tolerance" );
00139     clp.setOption( "abstol", &abstol, "Absolute Error Tolerance" );
00140     clp.setOption( "maxorder", &maxOrder, "Maximum Implicit BDF order" );
00141 #ifdef Rythmos_DEBUG
00142     clp.setOption( "debuglevel", &debugLevel, "Debug Level for Rythmos" );
00143 #endif // Rythmos_DEBUG
00144 
00145     Teuchos::CommandLineProcessor::EParseCommandLineReturn parse_return = clp.parse(argc,argv);
00146     if( parse_return != Teuchos::CommandLineProcessor::PARSE_SUCCESSFUL ) return parse_return;
00147 
00148 #ifdef HAVE_RYTHMOS_STRATIMIKOS
00149     lowsfCreator.readParameters(out.get());
00150     *out << "\nThe parameter list after being read in:\n";
00151     lowsfCreator.getParameterList()->print(*out,2,true,false);
00152 #endif
00153 
00154     if (version) // Display version information and exit.
00155     {
00156       *out << Rythmos::Rythmos_Version() << std::endl; 
00157       *out << "basicExample Version 0.1 - 06/23/05" << std::endl;
00158       return(0);
00159     }
00160 
00161     if (lambda_min > lambda_max)
00162     {
00163       *out << "lamba_min must be less than lambda_max" << std::endl;
00164       return(1);
00165     }
00166 
00167     if (finalTime <= 0.0)
00168     {
00169       *out << "Final simulation time must be > 0.0." << std::endl;
00170       return(1);
00171     }
00172 
00173 #ifdef Rythmos_DEBUG
00174     *out << std::setprecision(15);
00175 #endif // Rythmos_DEBUG
00176     
00177     // Set up the parameter list for the application:
00178     Teuchos::ParameterList params;
00179     bool implicitFlag = ((method_val==METHOD_BE) | (method_val==METHOD_BDF));
00180     //*out << "implicitFlag = " << implicitFlag << std::endl;
00181     params.set( "implicit", implicitFlag );
00182     params.set( "Lambda_min", lambda_min );
00183     params.set( "Lambda_max", lambda_max );
00184     params.set( "Lambda_fit", lambda_fit );
00185     params.set( "NumElements", numElements );
00186     params.set( "x0", x0 );
00187     params.set( "Coeff_s", coeff_s );
00188 #ifdef HAVE_MPI
00189     Teuchos::RefCountPtr<Epetra_Comm> epetra_comm_ptr_ = Teuchos::rcp( new Epetra_MpiComm(mpiComm) );
00190 #else
00191     Teuchos::RefCountPtr<Epetra_Comm> epetra_comm_ptr_ = Teuchos::rcp( new Epetra_SerialComm  );
00192 #endif // HAVE_MPI
00193 
00194     // Create the factory for the LinearOpWithSolveBase object
00195     Teuchos::RefCountPtr<Thyra::LinearOpWithSolveFactoryBase<double> >
00196       W_factory;
00197     if((method_val == METHOD_BE) | (method_val == METHOD_BDF)) {
00198 #ifdef HAVE_RYTHMOS_STRATIMIKOS
00199       W_factory = lowsfCreator.createLinearSolveStrategy("");
00200       *out
00201         << "\nCreated a LinearOpWithSolveFactory described as:\n"
00202         << Teuchos::describe(*W_factory,Teuchos::VERB_MEDIUM);
00203 #endif
00204     }
00205 
00206     // create interface to problem
00207     Teuchos::RefCountPtr<ExampleApplication>
00208       epetraModel = Teuchos::rcp(new ExampleApplication(epetra_comm_ptr_, params));
00209     Teuchos::RefCountPtr<Thyra::ModelEvaluator<double> >
00210       model = Teuchos::rcp(new Thyra::EpetraModelEvaluator(epetraModel,W_factory));
00211 
00212     // Create Stepper object depending on command-line input
00213     std::string method;
00214     Teuchos::RefCountPtr<Rythmos::Stepper<double> > stepper_ptr;
00215     if ( method_val == METHOD_ERK ) {
00216       stepper_ptr = Teuchos::rcp(new Rythmos::ExplicitRKStepper<double>(model));
00217       method = "Explicit Runge-Kutta of order 4";
00218       step_method_val = FIXED_STEP;
00219     } else if (method_val == METHOD_FE) {
00220       stepper_ptr = Teuchos::rcp(new Rythmos::ForwardEulerStepper<double>(model));
00221       method = "Forward Euler";
00222       step_method_val = FIXED_STEP;
00223     } else if ((method_val == METHOD_BE) | (method_val == METHOD_BDF)) {
00224       Teuchos::RefCountPtr<Thyra::NonlinearSolverBase<double> >
00225         nonlinearSolver;
00226       Teuchos::RefCountPtr<Thyra::TimeStepNewtonNonlinearSolver<double> >
00227         _nonlinearSolver = Teuchos::rcp(new Thyra::TimeStepNewtonNonlinearSolver<double>());
00228       _nonlinearSolver->defaultTol(1e-3*maxError);
00229       nonlinearSolver = _nonlinearSolver;
00230       if (method_val == METHOD_BE)
00231       {
00232         stepper_ptr = Teuchos::rcp(new Rythmos::BackwardEulerStepper<double>(model,nonlinearSolver));
00233         method = "Backward Euler";
00234         step_method_val = FIXED_STEP;
00235       } 
00236       else 
00237       {
00238         Teuchos::ParameterList BDFparams;
00239         BDFparams.set( "stopTime", finalTime );
00240         BDFparams.set( "maxOrder", maxOrder );
00241         BDFparams.set( "relErrTol", reltol );
00242         BDFparams.set( "absErrTol", abstol );
00243 #ifdef Rythmos_DEBUG
00244         BDFparams.set( "debugLevel", debugLevel );
00245 #endif // Rythmos_DEBUG
00246 
00247         stepper_ptr = Teuchos::rcp(new Rythmos::ImplicitBDFStepper<double>(model,nonlinearSolver,BDFparams));
00248         method = "Implicit BDF";
00249         // step_method_val setting is left alone in this case
00250       }
00251     } else {
00252       TEST_FOR_EXCEPT(true);
00253     }
00254     Rythmos::Stepper<double> &stepper = *stepper_ptr;
00255 #ifdef Rythmos_DEBUG
00256     Teuchos::RefCountPtr<Teuchos::FancyOStream> out = Teuchos::VerboseObjectBase::getDefaultOStream();
00257     if (debugLevel > 1)
00258     {
00259       stepper.describe(*out,Teuchos::VERB_EXTREME);
00260     }
00261 #endif // Rythmos_DEBUG
00262 
00263     int numSteps = 0;
00264     double t0 = 0.0;
00265     double dt = (finalTime-t0)/N;
00266     double time = t0;
00267 
00268     if (step_method_val == FIXED_STEP)
00269     {
00270       // Integrate forward with fixed step sizes:
00271       for (int i=1 ; i<=N ; ++i)
00272       {
00273         double dt_taken = stepper.TakeStep(dt);
00274         time += dt_taken;
00275         numSteps++;
00276 #ifdef Rythmos_DEBUG
00277         if (debugLevel > 1)
00278         {
00279           stepper.describe(*out,Teuchos::VERB_EXTREME);
00280         }
00281 #endif // Rythmos_DEBUG
00282         if (dt_taken != dt)
00283         {
00284           cerr << "Error, stepper took step of dt = " << dt_taken << " when asked to take step of dt = " << dt << std::endl;
00285           break;
00286         }
00287       }
00288     }
00289     else // (step_method_val == VARIABLE_STEP)
00290     {
00291 #ifdef Rythmos_DEBUG
00292       // Create a place to store the computed solutions
00293       Teuchos::RefCountPtr<const Thyra::VectorBase<double> > x_computed_thyra_ptr = stepper.get_solution();
00294       // Convert Thyra::VectorBase to Epetra_Vector
00295       Teuchos::RefCountPtr<const Epetra_Vector> x_computed_ptr = Thyra::get_Epetra_Vector(*(epetraModel->get_x_map()),x_computed_thyra_ptr);
00296       // Create a place to store the exact numerical solution
00297       Teuchos::RefCountPtr<Epetra_Vector> x_numerical_exact_ptr = Teuchos::rcp(new Epetra_Vector(x_computed_ptr->Map()));
00298       Epetra_Vector& x_numerical_exact = *x_numerical_exact_ptr;
00299       // Create a place to store the relative difference:
00300       Teuchos::RefCountPtr<Epetra_Vector> x_rel_diff_ptr = Teuchos::rcp(new Epetra_Vector(x_computed_ptr->Map()));
00301       Epetra_Vector& x_rel_diff = *x_rel_diff_ptr;
00302       // get lambda from the problem:
00303       Teuchos::RefCountPtr<const Epetra_Vector> lambda_ptr = epetraModel->get_coeff();
00304       const Epetra_Vector &lambda = *lambda_ptr;
00305 #endif // Rythmos_DEBUG
00306       while (time < finalTime)
00307       {
00308         double dt_taken = stepper.TakeStep();
00309         numSteps++;
00310 #ifdef Rythmos_DEBUG
00311         if (debugLevel > 1)
00312         {
00313           stepper.describe(*out,Teuchos::VERB_EXTREME);
00314         }
00315 #endif // Rythmos_DEBUG
00316         if (dt_taken < 0)
00317         {
00318           *out << "Error, stepper failed for some reason with step taken = " << dt_taken << endl;
00319           break;
00320         }
00321 #ifdef Rythmos_DEBUG
00322         // Get solution out of stepper:
00323         x_computed_thyra_ptr = stepper.get_solution();
00324         // Convert Thyra::VectorBase to Epetra_Vector
00325         x_computed_ptr = Thyra::get_Epetra_Vector(*(epetraModel->get_x_map()),x_computed_thyra_ptr);
00326         if ((method_val == METHOD_BDF) && (maxOrder == 1))
00327         {
00328           int myN = x_numerical_exact.MyLength();
00329           if (numSteps == 1) // First step
00330           {
00331             for (int i=0 ; i<myN ; ++i)
00332               x_numerical_exact[i] = x0;
00333           }
00334           for (int i=0 ; i<myN ; ++i)
00335             x_numerical_exact[i] = ( x_numerical_exact[i]
00336                  +dt_taken*epetraModel->evalR(time+dt_taken,lambda[i],coeff_s))
00337                  /(1-lambda[i]*dt_taken);
00338           for (int i=0 ; i<myN ; ++i)
00339             x_rel_diff[i] = (x_numerical_exact[i]-(*x_computed_ptr)[i])/x_numerical_exact[i];
00340           if (myN == 1)
00341             *out << "Computed x(" << time+dt_taken << ") = " << (*x_computed_ptr)[0] 
00342                  << "  Numerical Exact = " << x_numerical_exact[0] 
00343                  << "  Rel Diff = " << x_rel_diff[0] << std::endl;
00344           else
00345           {
00346             for (int i=0 ; i<myN ; ++i)
00347               *out << "Computed x_" << i << "(" << time+dt_taken << ") = " << (*x_computed_ptr)[i] 
00348                    << "  Numerical Exact = " << x_numerical_exact[i] 
00349                    << "  Rel Diff = " << x_rel_diff[i] <<  std::endl;
00350           }
00351         }
00352         else
00353         {
00354           // compute exact answer
00355           Teuchos::RefCountPtr<const Epetra_Vector> x_star_ptr = epetraModel->get_exact_solution(time);
00356           const Epetra_Vector& x_star = *x_star_ptr;
00357           int myN = x_computed_ptr->MyLength();
00358           for (int i=0 ; i<myN ; ++i)
00359             x_rel_diff[i] = (x_star[i]-(*x_computed_ptr)[i])/x_star[i];
00360           if (myN == 1)
00361             *out << "Computed x(" << time+dt_taken << ") = " << (*x_computed_ptr)[0] 
00362                  << "  Exact = " << x_star[0] 
00363                  << "  Rel Diff = " << x_rel_diff[0] << std::endl;
00364           else
00365           {
00366             for (int i=0 ; i<myN ; ++i)
00367               *out << "Computed x_" << i << "(" << time+dt_taken << ") = " << (*x_computed_ptr)[i] 
00368                    << "  Exact = " << x_star[i] 
00369                    << "  Rel Diff = " << x_rel_diff[i] << std::endl;
00370           }
00371         }
00372 
00373 #endif // Rythmos_DEBUG
00374         time += dt_taken;
00375         *out << "Took stepsize of: " << dt_taken << " time = " << time << endl;
00376       }
00377     }
00378     *out << "Integrated to time = " << time << endl;
00379 
00380     // Get solution out of stepper:
00381     Teuchos::RefCountPtr<const Thyra::VectorBase<double> > x_computed_thyra_ptr = stepper.get_solution();
00382     // Convert Thyra::VectorBase to Epetra_Vector
00383     Teuchos::RefCountPtr<const Epetra_Vector>
00384       x_computed_ptr = Thyra::get_Epetra_Vector(*(epetraModel->get_x_map()),x_computed_thyra_ptr);
00385     const Epetra_Vector &x_computed = *x_computed_ptr;
00386 
00387     // compute exact answer
00388     Teuchos::RefCountPtr<const Epetra_Vector> x_star_ptr = epetraModel->get_exact_solution(finalTime);
00389     const Epetra_Vector& x_star = *x_star_ptr;
00390     
00391     // get lambda from the problem:
00392     Teuchos::RefCountPtr<const Epetra_Vector> lambda_ptr = epetraModel->get_coeff();
00393     const Epetra_Vector &lambda = *lambda_ptr;
00394 
00395     // compute numerical exact answer (for FE and BE)
00396     Teuchos::RefCountPtr<const Epetra_Vector> x_numerical_exact_ptr; 
00397     if (method_val == METHOD_FE) 
00398     {
00399       Teuchos::RefCountPtr<Epetra_Vector> x_exact_ptr = Teuchos::rcp(new Epetra_Vector(x_star.Map()));
00400       Epetra_Vector& x_exact = *x_exact_ptr;
00401       int myN = x_exact.MyLength();
00402       for ( int i=0 ; i<myN ; ++i)
00403       {
00404         x_exact[i] = x0;
00405         for (int j=1 ; j<=N ; ++j)
00406         {
00407           x_exact[i] = (1+lambda[i]*dt)*x_exact[i]+dt*epetraModel->evalR(0+j*dt,lambda[i],coeff_s);
00408         }
00409         //x_exact[i] = x0*pow(1+lambda[i]*dt,N);
00410       }
00411       x_numerical_exact_ptr = x_exact_ptr;
00412     } 
00413     else if (method_val == METHOD_BE) 
00414     {
00415       Teuchos::RefCountPtr<Epetra_Vector> x_exact_ptr = Teuchos::rcp(new Epetra_Vector(x_star.Map()));
00416       Epetra_Vector& x_exact = *x_exact_ptr;
00417       int myN = x_exact.MyLength();
00418       for ( int i=0 ; i<myN ; ++i)
00419       {
00420         x_exact[i] = x0;
00421         for (int j=1 ; j<=N ; ++j)
00422         {
00423           x_exact[i] = (x_exact[i]+dt*epetraModel->evalR(0+j*dt,lambda[i],coeff_s))/(1-lambda[i]*dt);
00424         }
00425         //x_exact[i] = x0*pow(1/(1-lambda[i]*dt),N);
00426       }
00427       x_numerical_exact_ptr = x_exact_ptr;
00428     }
00429     else if (method_val == METHOD_BDF)
00430     {
00431       // exact bdf solution here?
00432     }
00433 
00434     // 06/03/05 tscoffe to get an Epetra_Map associated with an Epetra_Vector:
00435     // x.Map()
00436     // to get an Epetra_Comm associated with an Epetra_Vector:
00437     // x.Comm()
00438     
00439     int MyPID = x_computed.Comm().MyPID();
00440     if (MyPID == 0)
00441     {
00442       *out << "Integrating \\dot{x}=\\lambda x from t = " << t0 
00443                 << " to t = " << finalTime << std::endl;
00444       *out << "using " << method << std::endl;
00445       *out << "with initial x_0 = " << x0
00446                 << ", \\Delta t = " << dt  << "." << std::endl;
00447       *out << "Took " << numSteps << " steps." << std::endl;
00448     }
00449     int MyLength = x_computed.MyLength();
00450     if (verbose)
00451     {
00452       for (int i=0 ; i<MyLength ; ++i)
00453       {
00454         *out << std::setprecision(15);
00455         *out << "lambda[" << MyPID*MyLength+i << "] = " << lambda[i] << std::endl;
00456       }
00457       // Print out computed and exact solutions:
00458       for (int i=0 ; i<MyLength ; ++i)
00459       {
00460         *out << std::setprecision(15);
00461         *out << "Computed: x[" << MyPID*MyLength+i << "] = ";
00462         *out << std::setw(20) << x_computed[i] << "\t";
00463         *out << "Exact: x[" << MyPID*MyLength+i << "] = ";
00464         *out << std::setw(20) << x_star[i] << std::endl;
00465       }
00466     }
00467     
00468     // Check numerics against exact numerical method for FE and BE case:
00469     double numerical_error = 0;
00470     double numerical_error_mag = 0;
00471     if (x_numerical_exact_ptr.get())
00472     {
00473       const Epetra_Vector& x_numerical_exact = *x_numerical_exact_ptr;
00474       for ( int i=0 ; i<MyLength ; ++i)
00475       {
00476         if (verbose) 
00477         {
00478           *out << std::setprecision(15);
00479           *out << "Computed: x[" << MyPID*MyLength+i << "] = ";
00480           *out << std::setw(20) << x_computed[i] << "\t";
00481           *out << "Numerical Exact: x[" << MyPID*MyLength+i << "] = ";
00482           *out << std::setw(20) << x_numerical_exact[i] << std::endl;
00483         }
00484         const double thisError = x_numerical_exact[i]-x_computed[i];
00485         numerical_error += thisError*thisError;
00486         numerical_error_mag += x_numerical_exact[i]*x_numerical_exact[i];
00487       }
00488       numerical_error = sqrt(numerical_error)/sqrt(numerical_error_mag);
00489       result = Thyra::testMaxErr(
00490         "Exact numerical error",numerical_error
00491         ,"maxError",1.0e-10
00492         ,"maxWarning",1.0e-9
00493         ,&*out,""
00494         );
00495       if(!result) success = false;
00496     }
00497 
00498     // Check numerics against exact DE solution:
00499     double error = 0;
00500     double errorMag = 0;
00501     for (int i=0 ; i<MyLength ; ++i)
00502     {
00503       const double thisError = x_computed[i]-x_star[i];
00504       error += thisError*thisError;
00505       errorMag += x_star[i]*x_star[i];
00506     }
00507     error = sqrt(error)/sqrt(errorMag);
00508     result = Thyra::testMaxErr(
00509       "Exact DE solution error",error
00510       ,"maxError",maxError
00511       ,"maxWarning",10.0*maxError
00512       ,&*out,""
00513       );
00514     if(!result) success = false;
00515 
00516 #ifdef HAVE_RYTHMOS_STRATIMIKOS
00517     // Write the final parameters to file
00518     if(W_factory.get())
00519       lowsfCreator.writeParamsFile(*W_factory);
00520 #endif
00521 
00522    } // end try
00523   TEUCHOS_STANDARD_CATCH_STATEMENTS(true,*out,success)
00524 
00525   return success ? 0 : 1;
00526 
00527 } // end main() [Doxygen looks for this!]

Generated on Thu Sep 18 12:30:05 2008 for Rythmos - Transient Integration for Differential Equations by doxygen 1.3.9.1