diagonalTransientMain.cpp

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 "EpetraExt_DiagonalTransientModel.hpp"
00031 #include "Rythmos_BackwardEulerStepper.hpp"
00032 #include "Rythmos_ImplicitBDFStepper.hpp"
00033 #include "Rythmos_ImplicitRKStepper.hpp"
00034 #include "Rythmos_ForwardSensitivityStepper.hpp"
00035 #include "Rythmos_TimeStepNonlinearSolver.hpp"
00036 #include "Rythmos_DefaultIntegrator.hpp"
00037 #include "Rythmos_SimpleIntegrationControlStrategy.hpp"
00038 #include "Rythmos_StepperAsModelEvaluator.hpp"
00039 #include "Stratimikos_DefaultLinearSolverBuilder.hpp"
00040 #include "Thyra_EpetraModelEvaluator.hpp"
00041 #include "Thyra_DirectionalFiniteDiffCalculator.hpp"
00042 #include "Thyra_TestingTools.hpp"
00043 #include "Teuchos_StandardCatchMacros.hpp"
00044 #include "Teuchos_GlobalMPISession.hpp"
00045 #include "Teuchos_DefaultComm.hpp"
00046 #include "Teuchos_VerboseObject.hpp"
00047 #include "Teuchos_XMLParameterListHelpers.hpp"
00048 #include "Teuchos_CommandLineProcessor.hpp"
00049 #include "Teuchos_VerbosityLevelCommandLineProcessorHelpers.hpp"
00050 #include "Teuchos_as.hpp"
00051 
00052 #ifdef HAVE_MPI
00053 #  include "Epetra_MpiComm.h"
00054 #else
00055 #  include "Epetra_SerialComm.h"
00056 #endif // HAVE_MPI
00057 
00058 
00059 namespace {
00060 
00061 
00062 const std::string TimeStepNonlinearSolver_name = "TimeStepNonlinearSolver";
00063 
00064 const std::string Stratimikos_name = "Stratimikos";
00065 
00066 const std::string DiagonalTransientModel_name = "DiagonalTransientModel";
00067 
00068 const std::string RythmosStepper_name = "Rythmos Stepper";
00069 
00070 const std::string RythmosIntegrator_name = "Rythmos Integrator";
00071 
00072 const std::string FdCalc_name = "FD Calc";
00073 
00074 
00075 Teuchos::RCP<const Teuchos::ParameterList>
00076 getValidParameters()
00077 {
00078   using Teuchos::RCP; using Teuchos::ParameterList;
00079   static RCP<const ParameterList> validPL;
00080   if (is_null(validPL)) {
00081     RCP<ParameterList> pl = Teuchos::parameterList();
00082     pl->sublist(TimeStepNonlinearSolver_name);
00083     pl->sublist(Stratimikos_name);
00084     pl->sublist(DiagonalTransientModel_name);
00085     pl->sublist(RythmosStepper_name);
00086     pl->sublist(RythmosIntegrator_name);
00087     pl->sublist(FdCalc_name);
00088     validPL = pl;
00089   }
00090   return validPL;
00091 }
00092 
00093 
00094 } // namespace
00095 
00096 int main(int argc, char *argv[])
00097 {
00098 
00099   using std::endl;
00100   typedef double Scalar;
00101   typedef double ScalarMag;
00102   using Teuchos::describe;
00103   using Teuchos::RCP;
00104   using Teuchos::rcp;
00105   using Teuchos::rcp_implicit_cast;
00106   using Teuchos::rcp_dynamic_cast;
00107   using Teuchos::as;
00108   using Teuchos::ParameterList;
00109   using Teuchos::CommandLineProcessor;
00110   typedef Teuchos::ParameterList::PrintOptions PLPrintOptions;
00111   typedef Thyra::ModelEvaluatorBase MEB;
00112   typedef Thyra::DefaultMultiVectorProductVectorSpace<Scalar> DMVPVS;
00113   using Thyra::productVectorBase;
00114   
00115   bool result, success = true;
00116 
00117   Teuchos::GlobalMPISession mpiSession(&argc,&argv);
00118 
00119   RCP<Epetra_Comm> epetra_comm;
00120 #ifdef HAVE_MPI
00121   epetra_comm = rcp( new Epetra_MpiComm(MPI_COMM_WORLD) );
00122 #else
00123   epetra_comm = rcp( new Epetra_SerialComm );
00124 #endif // HAVE_MPI
00125 
00126   RCP<Teuchos::FancyOStream>
00127     out = Teuchos::VerboseObjectBase::getDefaultOStream();
00128 
00129   try {
00130 
00131     //
00132     // Read commandline options
00133     //
00134 
00135     CommandLineProcessor clp;
00136     clp.throwExceptions(false);
00137     clp.addOutputSetupOptions(true);
00138 
00139     std::string paramsFileName = "";
00140     clp.setOption( "params-file", &paramsFileName,
00141       "File name for XML parameters" );
00142 
00143     std::string extraParamsString = "";
00144     clp.setOption( "extra-params", &extraParamsString,
00145       "Extra XML parameters" );
00146 
00147     double maxStateError = 1e-6;
00148     clp.setOption( "max-state-error", &maxStateError,
00149       "The maximum allowed error in the integrated state in relation to the exact state solution" );
00150 
00151     double finalTime = 1e-3;
00152     clp.setOption( "final-time", &finalTime,
00153       "Final integration time (initial time is 0.0)" );
00154 
00155     int numTimeSteps = 10;
00156     clp.setOption( "num-time-steps", &numTimeSteps,
00157       "Number of (fixed) time steps.  If <= 0.0, then variable time steps are taken" );
00158 
00159     bool useBDF = false;
00160     clp.setOption( "use-BDF", "use-BE", &useBDF,
00161       "Use BDF or Backward Euler (BE)" );
00162 
00163     bool useIRK = false;
00164     clp.setOption( "use-IRK", "use-other", &useIRK,
00165       "Use IRK or something" );
00166 
00167     bool doFwdSensSolve = false;
00168     clp.setOption( "fwd-sens-solve", "state-solve", &doFwdSensSolve,
00169       "Do the forward sensitivity solve or just the state solve" );
00170 
00171     bool doFwdSensErrorControl = false;
00172     clp.setOption( "fwd-sens-err-cntrl", "no-fwd-sens-err-cntrl", &doFwdSensErrorControl,
00173       "Do error control on the forward sensitivity solve or not" );
00174 
00175     double maxRestateError = 0.0;
00176     clp.setOption( "max-restate-error", &maxRestateError,
00177       "The maximum allowed error between the state integrated by itself verses integrated along with DxDp" );
00178 
00179     double maxSensError = 1e-4;
00180     clp.setOption( "max-sens-error", &maxSensError,
00181       "The maximum allowed error in the integrated sensitivity in relation to"
00182       " the finite-difference sensitivity" );
00183 
00184     Teuchos::EVerbosityLevel verbLevel = Teuchos::VERB_DEFAULT;
00185     setVerbosityLevelOption( "verb-level", &verbLevel,
00186       "Top-level verbosity level.  By default, this gets deincremented as you go deeper into numerical objects.",
00187       &clp );
00188 
00189     bool testExactSensitivity = false;
00190     clp.setOption( "test-exact-sens", "no-test-exact-sens", &testExactSensitivity,
00191       "Test the exact sensitivity with finite differences or not." );
00192 
00193     bool dumpFinalSolutions = false;
00194     clp.setOption(
00195       "dump-final-solutions", "no-dump-final-solutions", &dumpFinalSolutions,
00196       "Determine if the final solutions are dumpped or not." );
00197     
00198     CommandLineProcessor::EParseCommandLineReturn parse_return = clp.parse(argc,argv);
00199     if( parse_return != CommandLineProcessor::PARSE_SUCCESSFUL ) return parse_return;
00200     
00201     if ( Teuchos::VERB_DEFAULT == verbLevel )
00202       verbLevel = Teuchos::VERB_LOW;
00203 
00204     const Teuchos::EVerbosityLevel
00205       solnVerbLevel = ( dumpFinalSolutions ? Teuchos::VERB_EXTREME : verbLevel );
00206 
00207     //
00208     // Get the base parameter list that all other parameter lists will be read
00209     // from.
00210     //
00211     
00212     RCP<ParameterList>
00213       paramList = Teuchos::parameterList();
00214     if (paramsFileName.length())
00215       updateParametersFromXmlFile( paramsFileName, &*paramList );
00216     if (extraParamsString.length())
00217       updateParametersFromXmlString( extraParamsString, &*paramList );
00218 
00219     if (testExactSensitivity) {
00220       paramList->sublist(DiagonalTransientModel_name).set("Exact Solution as Response",true);
00221     }
00222 
00223     paramList->validateParameters(*getValidParameters(),0); // Only validate top level lists!
00224 
00225     //
00226     // Create the Stratimikos linear solver factory.
00227     //
00228     // This is the linear solve strategy that will be used to solve for the
00229     // linear system with the W.
00230     //
00231 
00232     Stratimikos::DefaultLinearSolverBuilder linearSolverBuilder;
00233     linearSolverBuilder.setParameterList(sublist(paramList,Stratimikos_name));
00234     RCP<Thyra::LinearOpWithSolveFactoryBase<Scalar> >
00235       W_factory = createLinearSolveStrategy(linearSolverBuilder);
00236     
00237     //
00238     // Create the underlying EpetraExt::ModelEvaluator
00239     //
00240 
00241     RCP<EpetraExt::DiagonalTransientModel>
00242       epetraStateModel = EpetraExt::diagonalTransientModel(
00243         epetra_comm,
00244         sublist(paramList,DiagonalTransientModel_name)
00245         );
00246 
00247     *out <<"\nepetraStateModel valid options:\n";
00248     epetraStateModel->getValidParameters()->print(
00249       *out, PLPrintOptions().indent(2).showTypes(true).showDoc(true)
00250       );
00251     
00252     //
00253     // Create the Thyra-wrapped ModelEvaluator
00254     //
00255     
00256     RCP<Thyra::ModelEvaluator<double> >
00257       stateModel = epetraModelEvaluator(epetraStateModel,W_factory);
00258 
00259     *out << "\nParameter names = " << *stateModel->get_p_names(0) << "\n";
00260     
00261     //
00262     // Create the Rythmos stateStepper
00263     //
00264 
00265     RCP<Rythmos::TimeStepNonlinearSolver<double> >
00266       nonlinearSolver = Rythmos::timeStepNonlinearSolver<double>();
00267     RCP<ParameterList>
00268       nonlinearSolverPL = sublist(paramList,TimeStepNonlinearSolver_name);
00269     nonlinearSolverPL->get("Default Tol",1e-3*maxStateError); // Set default if not set
00270     nonlinearSolver->setParameterList(nonlinearSolverPL);
00271 
00272     RCP<Rythmos::StepperBase<Scalar> > stateStepper;
00273 
00274     if (useBDF) {
00275       stateStepper = rcp(
00276         new Rythmos::ImplicitBDFStepper<double>(
00277           stateModel, nonlinearSolver
00278           )
00279         );
00280     }
00281     else if (useIRK) {
00282       // We need a separate LOWSFB object for the IRK stepper
00283       RCP<Thyra::LinearOpWithSolveFactoryBase<Scalar> >
00284         irk_W_factory = createLinearSolveStrategy(linearSolverBuilder);
00285       stateStepper = Rythmos::implicitRKStepper<double>(
00286         stateModel, nonlinearSolver, irk_W_factory
00287         );
00288     }
00289     else {
00290       stateStepper = rcp(
00291         new Rythmos::BackwardEulerStepper<double>(
00292           stateModel, nonlinearSolver
00293           )
00294         );
00295     }
00296 
00297     *out <<"\nstateStepper:\n" << describe(*stateStepper,verbLevel);
00298     *out <<"\nstateStepper valid options:\n";
00299     stateStepper->getValidParameters()->print(
00300       *out, PLPrintOptions().indent(2).showTypes(true).showDoc(true)
00301       );
00302 
00303     stateStepper->setParameterList(sublist(paramList,RythmosStepper_name));
00304 
00305     //
00306     // Setup finite difference objects that will be used for tests
00307     //
00308 
00309     Thyra::DirectionalFiniteDiffCalculator<Scalar> fdCalc;
00310     fdCalc.setParameterList(sublist(paramList,FdCalc_name));
00311     fdCalc.setOStream(out);
00312     fdCalc.setVerbLevel(verbLevel);
00313 
00314     //
00315     // Use a StepperAsModelEvaluator to integrate the state
00316     //
00317 
00318     const MEB::InArgs<Scalar>
00319       state_ic = stateModel->getNominalValues();
00320     *out << "\nstate_ic:\n" << describe(state_ic,verbLevel);
00321 
00322     RCP<Rythmos::IntegratorBase<Scalar> > integrator;
00323     {
00324       RCP<ParameterList>
00325         integratorPL = sublist(paramList,RythmosIntegrator_name);
00326       integratorPL->set( "Take Variable Steps", as<bool>(numTimeSteps < 0) );
00327       integratorPL->set( "Fixed dt", as<double>((finalTime - state_ic.get_t())/numTimeSteps) );
00328       RCP<Rythmos::IntegratorBase<Scalar> >
00329         defaultIntegrator = Rythmos::controlledDefaultIntegrator<Scalar>(
00330           Rythmos::simpleIntegrationControlStrategy<Scalar>(integratorPL)
00331           );
00332       integrator = defaultIntegrator;
00333     }
00334 
00335     RCP<Rythmos::StepperAsModelEvaluator<Scalar> >
00336       stateIntegratorAsModel = Rythmos::stepperAsModelEvaluator(
00337         stateStepper, integrator, state_ic
00338         );
00339     stateIntegratorAsModel->setVerbLevel(verbLevel);
00340     
00341     *out << "\nUse the StepperAsModelEvaluator to integrate state x(p,finalTime) ... \n";
00342     
00343     RCP<Thyra::VectorBase<Scalar> > x_final;
00344 
00345     {
00346       
00347       Teuchos::OSTab tab(out);
00348 
00349       x_final = createMember(stateIntegratorAsModel->get_g_space(0));
00350       
00351       eval_g(
00352         *stateIntegratorAsModel,
00353         0, *state_ic.get_p(0),
00354         finalTime,
00355         0, &*x_final
00356         );
00357 
00358       *out
00359         << "\nx_final = x(p,finalTime) evaluated using stateIntegratorAsModel:\n"
00360         << describe(*x_final,solnVerbLevel);
00361 
00362     }
00363 
00364     //
00365     // Test the integrated state against the exact analytical state solution
00366     //
00367 
00368     RCP<const Thyra::VectorBase<Scalar> >
00369       exact_x_final = create_Vector(
00370         epetraStateModel->getExactSolution(finalTime),
00371         stateModel->get_x_space()
00372         );
00373     
00374     result = Thyra::testRelNormDiffErr(
00375       "exact_x_final", *exact_x_final, "x_final", *x_final,
00376       "maxStateError", maxStateError, "warningTol", 1.0, // Don't warn
00377       &*out, solnVerbLevel
00378       );
00379     if (!result) success = false;
00380 
00381     //
00382     // Solve and test the forward sensitivity computation
00383     //
00384       
00385     if (doFwdSensSolve) {
00386 
00387       //
00388       // Create the forward sensitivity stepper
00389       //
00390       
00391       RCP<Rythmos::ForwardSensitivityStepper<Scalar> > stateAndSensStepper = 
00392         Rythmos::forwardSensitivityStepper<Scalar>();
00393       if (doFwdSensErrorControl) {
00394         stateAndSensStepper->initializeDecoupledSteppers(
00395           stateModel, 0, stateModel->getNominalValues(),
00396           stateStepper, nonlinearSolver,
00397           integrator->cloneIntegrator(), finalTime
00398           );
00399       }
00400       else {
00401         stateAndSensStepper->initializeSyncedSteppers(
00402           stateModel, 0, stateModel->getNominalValues(),
00403           stateStepper, nonlinearSolver
00404           );
00405         // The above call will result in stateStepper and nonlinearSolver being
00406         // cloned.  This helps to ensure consistency between the state and
00407         // sensitivity computations!
00408       }
00409 
00410       //
00411       // Set the initial condition for the state and forward sensitivities
00412       //
00413 
00414       RCP<Thyra::VectorBase<Scalar> > s_bar_init
00415         = createMember(stateAndSensStepper->getFwdSensModel()->get_x_space());
00416       assign( &*s_bar_init, 0.0 );
00417       RCP<Thyra::VectorBase<Scalar> > s_bar_dot_init
00418         = createMember(stateAndSensStepper->getFwdSensModel()->get_x_space());
00419       assign( &*s_bar_dot_init, 0.0 );
00420       // Above, I believe that these are the correct initial conditions for
00421       // s_bar and s_bar_dot given how the EpetraExt::DiagonalTransientModel
00422       // is currently implemented!
00423 
00424       RCP<const Rythmos::StateAndForwardSensitivityModelEvaluator<Scalar> >
00425         stateAndSensModel = stateAndSensStepper->getStateAndFwdSensModel();
00426 
00427       MEB::InArgs<Scalar>
00428         state_and_sens_ic = stateAndSensStepper->getModel()->createInArgs();
00429 
00430       // Copy time, parameters etc.
00431       state_and_sens_ic.setArgs(state_ic);
00432       // Set initial condition for x_bar = [ x; s_bar ]
00433       state_and_sens_ic.set_x(
00434         stateAndSensModel->create_x_bar_vec(state_ic.get_x(),s_bar_init)
00435         );
00436       // Set initial condition for x_bar_dot = [ x_dot; s_bar_dot ]
00437       state_and_sens_ic.set_x_dot(
00438         stateAndSensModel->create_x_bar_vec(state_ic.get_x_dot(),s_bar_dot_init)
00439         );
00440 
00441       *out << "\nstate_and_sens_ic:\n" << describe(state_and_sens_ic,verbLevel);
00442  
00443       stateAndSensStepper->setInitialCondition(state_and_sens_ic);
00444 
00445       //
00446       // Use a StepperAsModelEvaluator to integrate the state+sens
00447       //
00448     
00449       RCP<Rythmos::StepperAsModelEvaluator<Scalar> >
00450         stateAndSensIntegratorAsModel = Rythmos::stepperAsModelEvaluator(
00451           rcp_implicit_cast<Rythmos::StepperBase<Scalar> >(stateAndSensStepper),
00452           integrator, state_and_sens_ic
00453           );
00454       stateAndSensIntegratorAsModel->setVerbLevel(verbLevel);
00455     
00456       *out << "\nUse the StepperAsModelEvaluator to integrate state + sens x_bar(p,finalTime) ... \n";
00457     
00458       RCP<Thyra::VectorBase<Scalar> > x_bar_final;
00459 
00460       {
00461       
00462         Teuchos::OSTab tab(out);
00463 
00464         x_bar_final = createMember(stateAndSensIntegratorAsModel->get_g_space(0));
00465       
00466         eval_g(
00467           *stateAndSensIntegratorAsModel,
00468           0, *state_ic.get_p(0),
00469           finalTime,
00470           0, &*x_bar_final
00471           );
00472 
00473         *out
00474           << "\nx_bar_final = x_bar(p,finalTime) evaluated using stateAndSensIntegratorAsModel:\n"
00475           << describe(*x_bar_final,solnVerbLevel);
00476 
00477       }
00478 
00479       //
00480       // Test that the state computed above is same as computed initially!
00481       //
00482 
00483       *out << "\nChecking that x(p,finalTime) computed as part of x_bar above is the same ...\n";
00484 
00485       {
00486 
00487         Teuchos::OSTab tab(out);
00488 
00489         RCP<const Thyra::VectorBase<Scalar> >
00490           x_in_x_bar_final = productVectorBase<Scalar>(x_bar_final)->getVectorBlock(0);
00491 
00492         result = Thyra::testRelNormDiffErr<Scalar>(
00493           "x_final", *x_final,
00494           "x_in_x_bar_final", *x_in_x_bar_final,
00495           "maxRestateError", maxRestateError,
00496           "warningTol", 1.0, // Don't warn
00497           &*out, solnVerbLevel
00498           );
00499         if (!result) success = false;
00500 
00501       }
00502 
00503       //
00504       // Compute DxDp using finite differences
00505       //
00506 
00507       *out << "\nApproximating DxDp(p,t) using directional finite differences of integrator for x(p,t) ...\n";
00508     
00509       RCP<Thyra::MultiVectorBase<Scalar> > DxDp_fd_final;
00510 
00511       {
00512       
00513         Teuchos::OSTab tab(out);
00514       
00515       
00516         MEB::InArgs<Scalar>
00517           fdBasePoint = stateIntegratorAsModel->createInArgs();
00518       
00519         fdBasePoint.set_t(finalTime);
00520         fdBasePoint.set_p(0,stateModel->getNominalValues().get_p(0));
00521       
00522         DxDp_fd_final = createMembers(
00523           stateIntegratorAsModel->get_g_space(0),
00524           stateIntegratorAsModel->get_p_space(0)->dim()
00525           );
00526       
00527         typedef Thyra::DirectionalFiniteDiffCalculatorTypes::SelectedDerivatives
00528           SelectedDerivatives;
00529       
00530         MEB::OutArgs<Scalar> fdOutArgs =
00531           fdCalc.createOutArgs(
00532             *stateIntegratorAsModel,
00533             SelectedDerivatives().supports(MEB::OUT_ARG_DgDp,0,0)
00534             );
00535         fdOutArgs.set_DgDp(0,0,DxDp_fd_final);
00536       
00537         // Silence the model evaluators that are called.  The fdCal object
00538         // will show all of the inputs and outputs for each call.
00539         stateStepper->setVerbLevel(Teuchos::VERB_NONE);
00540         stateIntegratorAsModel->setVerbLevel(Teuchos::VERB_NONE);
00541       
00542         fdCalc.calcDerivatives(
00543           *stateIntegratorAsModel, fdBasePoint,
00544           stateIntegratorAsModel->createOutArgs(), // Don't bother with function value
00545           fdOutArgs
00546           );
00547         
00548         *out
00549           << "\nFinite difference DxDp_fd_final = DxDp(p,finalTime): "
00550           << describe(*DxDp_fd_final,solnVerbLevel);
00551 
00552       }
00553 
00554       //
00555       // Test that the integrated sens and the F.D. sens are similar
00556       //
00557 
00558       *out << "\nChecking that integrated DxDp(p,finalTime) and finite-diff DxDp(p,finalTime) are similar ...\n";
00559 
00560       {
00561 
00562         Teuchos::OSTab tab(out);
00563 
00564         RCP<const Thyra::VectorBase<Scalar> >
00565           DxDp_vec_final = Thyra::productVectorBase<Scalar>(x_bar_final)->getVectorBlock(1);
00566       
00567         RCP<const Thyra::VectorBase<Scalar> >
00568           DxDp_fd_vec_final = Thyra::multiVectorProductVector(
00569             rcp_dynamic_cast<const Thyra::DefaultMultiVectorProductVectorSpace<Scalar> >(
00570               DxDp_vec_final->range()
00571               ),
00572             DxDp_fd_final
00573             );
00574 
00575         result = Thyra::testRelNormDiffErr(
00576           "DxDp_vec_final", *DxDp_vec_final,
00577           "DxDp_fd_vec_final", *DxDp_fd_vec_final,
00578           "maxSensError", maxSensError,
00579           "warningTol", 1.0, // Don't warn
00580           &*out, solnVerbLevel
00581           );
00582         if (!result) success = false;
00583 
00584       }
00585 
00586     }
00587     
00588   }
00589   TEUCHOS_STANDARD_CATCH_STATEMENTS(true,*out,success);
00590 
00591   if(success)
00592     *out << "\nEnd Result: TEST PASSED" << endl;
00593   else
00594     *out << "\nEnd Result: TEST FAILED" << endl;
00595   
00596   return ( success ? 0 : 1 );
00597 
00598 } // end main() [Doxygen looks for this!]
00599 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends

Generated on Tue Oct 20 10:24:08 2009 for Rythmos - Transient Integration for Differential Equations by  doxygen 1.6.1