diff --git a/packages/ifpack2/src/Ifpack2_Details_Chebyshev_def.hpp b/packages/ifpack2/src/Ifpack2_Details_Chebyshev_def.hpp index f5082e6a7c1d..718175c68aa9 100644 --- a/packages/ifpack2/src/Ifpack2_Details_Chebyshev_def.hpp +++ b/packages/ifpack2/src/Ifpack2_Details_Chebyshev_def.hpp @@ -733,7 +733,6 @@ setMatrix (const Teuchos::RCP& A) } } - template void Chebyshev::compute () @@ -862,11 +861,8 @@ Chebyshev::compute () //////////////////////////////////////////////////////////////////// // Always favor the user's max eigenvalue estimate, if provided. - if (STS::isnaninf (userLambdaMax_)) { - lambdaMaxForApply_ = computedLambdaMax_; - } else { - lambdaMaxForApply_ = userLambdaMax_; - } + lambdaMaxForApply_ = STS::isnaninf (userLambdaMax_) ? computedLambdaMax_ : userLambdaMax_; + // mfh 11 Feb 2013: For now, we imitate Ifpack by ignoring the // user's min eigenvalue estimate, and using the given eigenvalue // ratio to estimate the min eigenvalue. We could instead do this: diff --git a/packages/muelu/cmake/Dependencies.cmake b/packages/muelu/cmake/Dependencies.cmake index 0aa3aa078060..7298a8d1c0ea 100644 --- a/packages/muelu/cmake/Dependencies.cmake +++ b/packages/muelu/cmake/Dependencies.cmake @@ -3,8 +3,8 @@ SET(LIB_OPTIONAL_DEP_PACKAGES Amesos Amesos2 AvatarT Belos Epetra EpetraExt Teko Ifpack Ifpack2 Intrepid2 ML Tpetra Zoltan Zoltan2 Stratimikos Thyra ThyraTpetraAdapters Isorropia KokkosCore KokkosContainers KokkosKernels) -SET(TEST_REQUIRED_DEP_PACKAGES ) -SET(TEST_OPTIONAL_DEP_PACKAGES AztecOO Galeri Pamgen) +SET(TEST_REQUIRED_DEP_PACKAGES Galeri) +SET(TEST_OPTIONAL_DEP_PACKAGES AztecOO Pamgen) SET(LIB_REQUIRED_DEP_TPLS BLAS LAPACK) SET(LIB_OPTIONAL_DEP_TPLS Boost MATLAB AmgX CGAL ViennaCL MKL Avatar CUSPARSE MAGMASparse mlpack) SET(TEST_REQUIRED_DEP_TPLS) diff --git a/packages/muelu/src/Interface/MueLu_FactoryFactory_decl.hpp b/packages/muelu/src/Interface/MueLu_FactoryFactory_decl.hpp index c8a7e24a612a..3f54a9af042b 100644 --- a/packages/muelu/src/Interface/MueLu_FactoryFactory_decl.hpp +++ b/packages/muelu/src/Interface/MueLu_FactoryFactory_decl.hpp @@ -82,6 +82,7 @@ #include "MueLu_BrickAggregationFactory.hpp" #include "MueLu_CloneRepartitionInterface.hpp" #include "MueLu_CoalesceDropFactory.hpp" +#include "MueLu_SmooVecCoalesceDropFactory.hpp" #include "MueLu_CoarseMapFactory.hpp" #include "MueLu_CoarseningVisualizationFactory.hpp" #include "MueLu_ConstraintFactory.hpp" @@ -238,6 +239,7 @@ namespace MueLu { if (factoryName == "CoarseMapFactory") return Build2 (paramList, factoryMapIn, factoryManagersIn); if (factoryName == "CoarseningVisualizationFactory") return Build2 (paramList, factoryMapIn, factoryManagersIn); if (factoryName == "CoalesceDropFactory") return Build2 (paramList, factoryMapIn, factoryManagersIn); + if (factoryName == "SmooVecCoalesceDropFactory") return Build2 (paramList, factoryMapIn, factoryManagersIn); if (factoryName == "ConstraintFactory") return Build2 (paramList, factoryMapIn, factoryManagersIn); if (factoryName == "CoupledAggregationFactory") return BuildCoupledAggregationFactory (paramList, factoryMapIn, factoryManagersIn); if (factoryName == "CoordinatesTransferFactory") return Build2 (paramList, factoryMapIn, factoryManagersIn); diff --git a/packages/nox/src-thyra/NOX_MatrixFree_ModelEvaluatorDecorator.hpp b/packages/nox/src-thyra/NOX_MatrixFree_ModelEvaluatorDecorator.hpp index 64097872d57b..097943cae415 100644 --- a/packages/nox/src-thyra/NOX_MatrixFree_ModelEvaluatorDecorator.hpp +++ b/packages/nox/src-thyra/NOX_MatrixFree_ModelEvaluatorDecorator.hpp @@ -31,10 +31,10 @@ namespace NOX { outArgs.setModelEvalDescription(this->description()); if (outArgs.supports( ::Thyra::ModelEvaluatorBase::OUT_ARG_W_op)) - return outArgs; + return std::move(outArgs); outArgs.setSupports( ::Thyra::ModelEvaluatorBase::OUT_ARG_W_op,true); - return outArgs; + return std::move(outArgs); } void evalModelImpl(const ::Thyra::ModelEvaluatorBase::InArgs &inArgs, diff --git a/packages/nox/src-thyra/NOX_Thyra_MatrixFreeJacobianOperator.hpp b/packages/nox/src-thyra/NOX_Thyra_MatrixFreeJacobianOperator.hpp index d9130c10fdbd..5fc04581fd7e 100644 --- a/packages/nox/src-thyra/NOX_Thyra_MatrixFreeJacobianOperator.hpp +++ b/packages/nox/src-thyra/NOX_Thyra_MatrixFreeJacobianOperator.hpp @@ -64,7 +64,6 @@ namespace NOX { } namespace NOX { - namespace Thyra { /*! \brief Concrete implementation of a Thyra::LinearOpBase object that approximates a Jacobian operator based on the Jacobian-Free Newton-Krylov method (see Knoll and Keyes Journal of Computational Physics 193 (2004) 357-397 for details). @@ -208,9 +207,9 @@ class MatrixFreeJacobianOperator : public ::Thyra::LinearOpBase, }; -#include "NOX_Thyra_MatrixFreeJacobianOperator_impl.hpp" - } // namespace Thyra } // namespace NOX +#include "NOX_Thyra_MatrixFreeJacobianOperator_impl.hpp" + #endif /* NOX_EPETRA_MATRIXFREE_JACOBIAN_OPERATOR_HPP */ diff --git a/packages/nox/src-thyra/NOX_Thyra_MatrixFreeJacobianOperator_impl.hpp b/packages/nox/src-thyra/NOX_Thyra_MatrixFreeJacobianOperator_impl.hpp index 5dc9a570615d..af0ad4d25f64 100644 --- a/packages/nox/src-thyra/NOX_Thyra_MatrixFreeJacobianOperator_impl.hpp +++ b/packages/nox/src-thyra/NOX_Thyra_MatrixFreeJacobianOperator_impl.hpp @@ -51,6 +51,10 @@ #include "Teuchos_ParameterList.hpp" #include "Teuchos_StandardParameterEntryValidators.hpp" #include "Thyra_ModelEvaluatorBase.hpp" +#include "Thyra_VectorStdOps.hpp" + +namespace NOX { +namespace Thyra { template MatrixFreeJacobianOperator:: @@ -326,3 +330,6 @@ Scalar MatrixFreeJacobianOperator::getDelta() const { return delta_; } + +} // namespace Thyra +} // namespace NOX diff --git a/packages/rol/adapters/thyra/src/function/ROL_ThyraProductME_Objective.hpp b/packages/rol/adapters/thyra/src/function/ROL_ThyraProductME_Objective.hpp index 3e72d233bab5..a5745b8a8b2a 100644 --- a/packages/rol/adapters/thyra/src/function/ROL_ThyraProductME_Objective.hpp +++ b/packages/rol/adapters/thyra/src/function/ROL_ThyraProductME_Objective.hpp @@ -83,8 +83,8 @@ class ThyraProductME_Objective : public Objective { if(!computeValue) return value_; - Real norm = rol_x.norm(); - std::cout << "Value norm: " << norm << std::endl; + // Real norm = rol_x.norm(); + // std::cout << "Value norm: " << norm << std::endl; const ThyraVector & thyra_p = dynamic_cast&>(rol_x); Teuchos::RCP< Thyra::VectorBase > g = Thyra::createMember(thyra_model.get_g_space(g_index)); @@ -119,8 +119,8 @@ class ThyraProductME_Objective : public Objective { */ void gradient( Vector &rol_g, const Vector &rol_x, Real &tol ) { - Real norm = rol_x.norm(); - std::cout << "In Gradient, Value norm: " << norm << std::endl; + // Real norm = rol_x.norm(); + // std::cout << "In Gradient, Value norm: " << norm << std::endl; const ThyraVector & thyra_p = dynamic_cast&>(rol_x); Teuchos::RCP > thyra_prodvec_p = Teuchos::rcp_dynamic_cast>(thyra_p.getVector()); diff --git a/packages/tempus/src/Tempus_StepperForwardEulerAppAction.hpp b/packages/tempus/src/Tempus_StepperForwardEulerAppAction.hpp new file mode 100644 index 000000000000..4d7d2b2e57db --- /dev/null +++ b/packages/tempus/src/Tempus_StepperForwardEulerAppAction.hpp @@ -0,0 +1,73 @@ +// @HEADER +// **************************************************************************** +// Tempus: Copyright (2017) Sandia Corporation +// +// Distributed under BSD 3-clause license (See accompanying file Copyright.txt) +// **************************************************************************** +// @HEADER + +#ifndef Tempus_StepperForwardEulerAppAction_hpp +#define Tempus_StepperForwardEulerAppAction_hpp + +#include "Tempus_config.hpp" +#include "Tempus_SolutionHistory.hpp" +#include "Tempus_StepperForwardEuler.hpp" + + +namespace Tempus { + +// Forward Declaration for recursive includes (this AppAction <--> Stepper) +template class StepperForwardEuler; + +/** \brief Application Action for StepperForwardEuler. + * + * This class provides a means to apply various actions with the ForwardEuler time step. + * The data available to this class is solution variables (through + * SolutionHistory), and stepper data (through the Stepper). It allows + * the application to just observe this data (i.e., use but not change the + * data) to change any of it (USER BEWARE!). + * + * Below is the ForwardEuler algorithm and includes the locations where the + * application can take actions (in italicized). + * + * \f{algorithm}{ + * \renewcommand{\thealgorithm}{} + * \caption{Forward Euler with the locations of the application actions indicated.} + * \begin{algorithmic}[1] + * \State Start with $x_n$, $\Delta t_n$ + * \State {\it appAction.execute(solutionHistory, stepper, BEGIN\_STEP)} + * \State Form $f(x_{n},t_{n})$ + * \State {\it appAction.execute(solutionHistory, stepper, BEFORE\_EXPLICIT\_EVAL)} + * \State Form $x_n \leftarrow x_{n} + \Delta t_n f(x_{n},t_n)$ + * \State {\it appAction.execute(solutionHistory, stepper, END\_STEP)} + * \end{algorithmic} + * \f} + */ +template +class StepperForwardEulerAppAction +{ +public: + + /// Indicates the location of application action (see algorithm). + enum ACTION_LOCATION { + BEGIN_STEP, ///< At the beginning of the step. + BEFORE_EXPLICIT_EVAL, ///< Before the explicit evaluation. + END_STEP ///< At the end of the step. + }; + + /// Constructor + StepperForwardEulerAppAction(){} + + /// Destructor + virtual ~StepperForwardEulerAppAction(){} + + /// Execute application action for ForwardEuler Stepper. + virtual void execute( + Teuchos::RCP > sh, + Teuchos::RCP > stepper, + const typename StepperForwardEulerAppAction::ACTION_LOCATION actLoc) = 0; +}; + +} // namespace Tempus + +#endif // Tempus_StepperForwardEulerAppAction_hpp diff --git a/packages/tempus/src/Tempus_StepperForwardEulerAppActionComposite.hpp b/packages/tempus/src/Tempus_StepperForwardEulerAppActionComposite.hpp new file mode 100644 index 000000000000..0a27d2b26a24 --- /dev/null +++ b/packages/tempus/src/Tempus_StepperForwardEulerAppActionComposite.hpp @@ -0,0 +1,65 @@ +// @HEADER +// **************************************************************************** +// Tempus: Copyright (2017) Sandia Corporation +// +// Distributed under BSD 3-clause license (See accompanying file Copyright.txt) +// **************************************************************************** +// @HEADER + +#ifndef Tempus_StepperForwardEulerAppActionComposite_hpp +#define Tempus_StepperForwardEulerAppActionComposite_hpp + +#include "Tempus_StepperForwardEulerAppAction.hpp" +#include "Tempus_TimeStepControl.hpp" +#include + +namespace Tempus { + +/** \brief This composite AppAction loops over added AppActions. + * + * Inidividual AppActions are executed in the order in which they + * were added. + */ +template +class StepperForwardEulerAppActionComposite + : virtual public Tempus::StepperForwardEulerAppAction +{ +public: + + /// Default constructor + StepperForwardEulerAppActionComposite(); + + /// Destructor + virtual ~StepperForwardEulerAppActionComposite(); + + /// Execute application action for ForwardEuler Stepper. + virtual void execute( + Teuchos::RCP > sh, + Teuchos::RCP > stepper, + const typename StepperForwardEulerAppAction::ACTION_LOCATION actLoc) + { + for(auto& a : appActions_) + a->execute(sh, stepper, actLoc); + } + + // Add AppAction to the AppAction vector. + void addForwardEulerAppAction(Teuchos::RCP > appAction); + { + appActions_.push_back(appAction); + } + + // Clear the AppAction vector. + void clearForwardEulerAppActions(); + { appActions_.clear();} + + // Return the size of the AppAction vector. + std::size_t getSize() const { return appActions_.size(); } + +private: + + std::vector > > appActions_; + +}; + +} // namespace Tempus +#endif // Tempus_StepperForwardEulerAppActionComposite_hpp diff --git a/packages/tempus/src/Tempus_StepperForwardEulerModifierBase.hpp b/packages/tempus/src/Tempus_StepperForwardEulerModifierBase.hpp new file mode 100644 index 000000000000..e91d7b46ffdc --- /dev/null +++ b/packages/tempus/src/Tempus_StepperForwardEulerModifierBase.hpp @@ -0,0 +1,78 @@ +// @HEADER +// **************************************************************************** +// Tempus: Copyright (2017) Sandia Corporation +// +// Distributed under BSD 3-clause license (See accompanying file Copyright.txt) +// **************************************************************************** +// @HEADER + +#ifndef Tempus_StepperForwardEulerModifierBase_hpp +#define Tempus_StepperForwardEulerModifierBase_hpp + +#include "Tempus_config.hpp" +#include "Tempus_SolutionHistory.hpp" +#include "Tempus_StepperForwardEulerAppAction.hpp" + +namespace Tempus { + +/** \brief Base modifier for StepperBackwardEuler. + * + * This class provides a means to modify values (e.g., solution variables + * through SolutionHistory, and stepper member data through the Stepper), + * and can be very powerful and easy to make changes to the stepper and + * the solution. + * + * Users deriving from this class can access a lot of data, and it is + * expected that those users know what changes are allowable without + * affecting the Stepper correctness, performance, accuracy and stability. + * Thus the user should be careful when accessing data through classes + * derived from the default modifier (i.e., USER BEWARE!!). + * + * \f{algorithm}{ + * \renewcommand{\thealgorithm}{} + * \caption{Forward Euler with the locations of the application actions indicated.} + * \begin{algorithmic}[1] + * \State Start with $x_n$, $\Delta t_n$ + * \State {\it appAction.execute(solutionHistory, stepper, BEGIN\_STEP)} + * \State Form $f(x_{n},t_{n})$ + * \State {\it appAction.execute(solutionHistory, stepper, BEFORE\_EXPLICIT\_EVAL)} + * \State Form $x_n \leftarrow x_{n} + \Delta t_n f(x_{n},t_n)$ + * \State {\it appAction.execute(solutionHistory, stepper, END\_STEP)} + * \end{algorithmic} + * \f} + */ + +template +class StepperForwardEulerModifierBase + : virtual public Tempus::StepperForwardEulerAppAction +{ +private: + + /* \brief Adaptor execute function + * + * This is an adaptor function to bridge between the AppAction + * interface and the Modifier interface. It is meant to be private + * and non-virtual as deriving from this class should only need to + * implement the modify function. + * + * For the Modifier interface, this adaptor is a "simple pass through". + */ + void execute( + Teuchos::RCP > sh, + Teuchos::RCP > stepper, + const typename StepperForwardEulerAppAction::ACTION_LOCATION actLoc) + { this->modify(sh, stepper, actLoc); } + +public: + + /// Modify ForwardEuler Stepper. + virtual void modify( + Teuchos::RCP > /* sh */, + Teuchos::RCP > /* stepper */, + const typename StepperForwardEulerAppAction::ACTION_LOCATION actLoc) = 0; + +}; + +} // namespace Tempus + +#endif // Tempus_StepperForwardEulerModifierBase_hpp diff --git a/packages/tempus/src/Tempus_StepperForwardEulerModifierDefault.hpp b/packages/tempus/src/Tempus_StepperForwardEulerModifierDefault.hpp new file mode 100644 index 000000000000..0d63ec0b017f --- /dev/null +++ b/packages/tempus/src/Tempus_StepperForwardEulerModifierDefault.hpp @@ -0,0 +1,60 @@ +// @HEADER +// **************************************************************************** +// Tempus: Copyright (2017) Sandia Corporation +// +// Distributed under BSD 3-clause license (See accompanying file Copyright.txt) +// **************************************************************************** +// @HEADER + +#ifndef Tempus_StepperForwardEulerModifierDefault_hpp +#define Tempus_StepperForwardEulerModifierDefault_hpp + +#include "Tempus_config.hpp" +#include "Tempus_SolutionHistory.hpp" +#include "Tempus_StepperForwardEulerModifierBase.hpp" + + +namespace Tempus { + +/** \brief Default modifier for StepperForwardEuler. + * + * The default modifier provides no-op functionality for the modifier. + * See StepperForwardEulerModifierBase for details on the algorithm. + */ +template +class StepperForwardEulerModifierDefault + : virtual public Tempus::StepperForwardEulerModifierBase +{ +public: + + /// Constructor + StepperForwardEulerModifierDefault(){} + + /// Destructor + virtual ~StepperForwardEulerModifierDefault(){} + + /// Modify ForwardEuler Stepper. + virtual void modify( + Teuchos::RCP > /* sh */, + Teuchos::RCP > /* stepper */, + const typename StepperForwardEulerAppAction::ACTION_LOCATION actLoc) + { + switch(actLoc) { + case StepperForwardEulerAppAction::BEGIN_STEP: + case StepperForwardEulerAppAction::BEFORE_EXPLICIT_EVAL: + case StepperForwardEulerAppAction::END_STEP: + { + // No-op. + break; + } + default: + TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, + "Error - unknown action location.\n"); + } + } + +}; + +} // namespace Tempus + +#endif // Tempus_StepperForwardEulerModifierDefault_hpp diff --git a/packages/tempus/src/Tempus_StepperForwardEulerModifierXBase.hpp b/packages/tempus/src/Tempus_StepperForwardEulerModifierXBase.hpp new file mode 100644 index 000000000000..22f8c111e8f4 --- /dev/null +++ b/packages/tempus/src/Tempus_StepperForwardEulerModifierXBase.hpp @@ -0,0 +1,126 @@ +// @HEADER +// **************************************************************************** +// Tempus: Copyright (2017) Sandia Corporation +// +// Distributed under BSD 3-clause license (See accompanying file Copyright.txt) +// **************************************************************************** +// @HEADER + +#ifndef Tempus_StepperForwardEulerModifierXBase_hpp +#define Tempus_StepperFirwardEulerModifierXBase_hpp + +#include "Tempus_config.hpp" +#include "Tempus_SolutionHistory.hpp" +#include "Tempus_StepperForwardEulerAppAction.hpp" + + +namespace Tempus { + +/** \brief Base ModifierX for StepperForwardEuler. + * + * This class provides a means to modify just the solution values + * (i.e., \f$x\f$ and \f$dot{x}\f$), and nothing else, but time and + * timestep are also provided. + * + * Users deriving from this class can access and change the solution + * during the timestep (e.g., limiting the solution for monoticity). + * It is expected that the user knows what changes are allowable without + * affecting the Stepper correctness, performance, accuracy and stability + * (i.e., USER BEWARE!!). + * + * Below is the ForwardEuler algorithm with the locations of the ModifierX calls + * italicized. + * + * \f{algorithm}{ + * \renewcommand{\thealgorithm}{} + * \caption{Forward Euler with the locations of the application actions indicated} + * \begin{algorithmic}[1] + * \State Start with $x_n$, $\Delta t_n$ + * \State {\it appAction.execute(solutionHistory, stepper, BEGIN\_STEP)} + * \State Form $f(x_{n},t_{n})$ + * \State {\it appAction.execute(solutionHistory, stepper, BEFORE\_EXPLICIT\_EVAL)} + * \State Form $x_n \leftarrow x_{n} + \Delta t_n f(x_{n},t_n)$ + * \State {\it appAction.execute(solutionHistory, stepper, END\_STEP)} + * \end{algorithmic} + * \f} + */ + +template +class StepperForwardEulerModifierXBase + : virtual public Tempus::StepperForwardEulerAppAction +{ +private: + + /* \brief Adaptor execute function + * + * This is an adaptor function to bridge between the AppAction + * interface and the ModifierX interface. It is meant to be private + * and non-virtual as deriving from this class should only need to + * implement the modify function. + * + * For the ModifierX interface, this adaptor maps the + * StepperForwardEulerAppAction::ACTION_LOCATION to the + * StepperForwardEulerModifierX::MODIFIERX_TYPE, and only pass the solution + * (\f$x\f$ and/or \f$\dot{x}\f$ and other parameters to the modify + * function. + */ + void execute( + Teuchos::RCP > sh, + Teuchos::RCP > stepper, + const typename StepperForwardEulerAppAction::ACTION_LOCATION actLoc) + { + using Teuchos::RCP; + + MODIFIER_TYPE modType = X_BEGIN_STEP; + RCP > workingState = sh->getWorkingState(); + const Scalar time = workingState->getTime(); + const Scalar dt = workingState->getTimeStep(); + RCP > x; + + switch(actLoc) { + case StepperForwardEulerAppAction::BEGIN_STEP: + { + modType = X_BEGIN_STEP; + x = workingState->getX(); + break; + } + case StepperForwardEulerAppAction::BEFORE_EXPLICIT_EVAL: + { + modType = X_BEFORE_EXPLICIT_EVAL; + x = workingState->getX(); + break; + } + case StepperForwardEulerAppAction::END_STEP: + { + modType = XDOT_END_STEP; + x = stepper->getStepperXDot(workingState); + break; + } + default: + TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, + "Error - unknown action location.\n"); + } + + this->modify(x, time, dt, modType); + } + +public: + + /// Indicates the location of application action (see algorithm). + enum MODIFIER_TYPE { + X_BEGIN_STEP, ///< Modify \f$x\f$ at the beginning of the step. + X_BEFORE_EXPLICIT_EVAL, ///< Modify \f$x\f$ before the implicit solve. + XDOT_END_STEP ///< Modify \f$\dot{x}\f$ at the end of the step. + }; + + /// Modify solution based on the MODIFIER_TYPE. + virtual void modify( + Teuchos::RCP > /* x */, + const Scalar /* time */, const Scalar /* dt */, + const MODIFIER_TYPE modType) = 0; + +}; + +} // namespace Tempus + +#endif // Tempus_StepperForwardEulerModifierXBase_hpp diff --git a/packages/tempus/src/Tempus_StepperForwardEulerModifierXDefault.hpp b/packages/tempus/src/Tempus_StepperForwardEulerModifierXDefault.hpp new file mode 100644 index 000000000000..20d14ddd42d5 --- /dev/null +++ b/packages/tempus/src/Tempus_StepperForwardEulerModifierXDefault.hpp @@ -0,0 +1,60 @@ +// @HEADER +// **************************************************************************** +// Tempus: Copyright (2017) Sandia Corporation +// +// Distributed under BSD 3-clause license (See accompanying file Copyright.txt) +// **************************************************************************** +// @HEADER + +#ifndef Tempus_StepperForwardEulerModifierX_hpp +#define Tempus_StepperForwardEulerModifierX_hpp + +#include "Tempus_config.hpp" +#include "Tempus_SolutionHistory.hpp" +#include "Tempus_StepperForwardEulerModifierXBase.hpp" + + +namespace Tempus { + +/** \brief Default ModifierX for StepperForwardEuler. + * + * The default provides no-op functionality for ModifierX. + * See StepperForwardEulerModifierXBase for details on the algorithm. + */ +template +class StepperForwardEulerModifierXDefault + : virtual public Tempus::StepperForwardEulerModifierXBase +{ +public: + + /// Constructor + StepperForwardEulerModifierXDefault(){} + + /// Destructor + virtual ~StepperForwardEulerModifierXDefault(){} + + /// Modify solution based on the MODIFIER_TYPE. + virtual void modify( + Teuchos::RCP > /* x */, + const Scalar /* time */, const Scalar /* dt */, + const typename StepperForwardEulerModifierXBase::MODIFIER_TYPE modType) + { + switch(modType) { + case StepperForwardEulerModifierXBase::X_BEGIN_STEP: + case StepperForwardEulerModifierXBase::X_BEFORE_EXPLICIT_EVAL: + case StepperForwardEulerModifierXBase::XDOT_END_STEP: + { + // No-op. + break; + } + default: + TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, + "Error - unknown modifier type.\n"); + } + } + +}; + +} // namespace Tempus + +#endif // Tempus_StepperForwardEulerModifierX_hpp diff --git a/packages/tempus/src/Tempus_StepperForwardEulerObserverBase.hpp b/packages/tempus/src/Tempus_StepperForwardEulerObserverBase.hpp new file mode 100644 index 000000000000..2be2aabcb558 --- /dev/null +++ b/packages/tempus/src/Tempus_StepperForwardEulerObserverBase.hpp @@ -0,0 +1,80 @@ +// @HEADER +// **************************************************************************** +// Tempus: Copyright (2017) Sandia Corporation +// +// Distributed under BSD 3-clause license (See accompanying file Copyright.txt) +// **************************************************************************** +// @HEADER + +#ifndef Tempus_StepperForwardEulerObserverBase_hpp +#define Tempus_StepperForwardEulerObserverBase_hpp + +#include "Tempus_config.hpp" +#include "Tempus_SolutionHistory.hpp" +#include "Tempus_StepperForwardEulerAppAction.hpp" + + +namespace Tempus { + +/** \brief Base observer for StepperForwardEuler. + * + * This class provides a means to observe values (e.g., solution variables + * through SolutionHistory, and stepper member data through the Stepper), + * and cannot modify them. + * + * Users deriving from this class can observer a lot of data, and it is + * expected that users will NOT modify any of that data. If the user + * wishes to modify the solution and/or stepper data during the + * Stepper::takeStep, they should use the Modifier class (with care!). + * + * Below is the ForwardEuler algorithm with the locations of the observe calls + * italicized. + * + * \f{algorithm}{ + * \renewcommand{\thealgorithm}{} + * \caption{Forward Euler with the locations of the application actions indicated.} + * \begin{algorithmic}[1] + * \State Start with $x_n$, $\Delta t_n$ + * \State {\it appAction.execute(solutionHistory, stepper, BEGIN\_STEP)} + * \State Form $f(x_{n},t_{n})$ + * \State {\it appAction.execute(solutionHistory, stepper, BEFORE\_EXPLICIT\_EVAL)} + * \State Form $x_n \leftarrow x_{n} + \Delta t_n f(x_{n},t_n)$ + * \State {\it appAction.execute(solutionHistory, stepper, END\_STEP)} + * \end{algorithmic} + * \f} + */ +template +class StepperForwardEulerObserverBase + : virtual public Tempus::StepperForwardEulerAppAction +{ +private: + + /* \brief Adaptor execute function + * + * This is an adaptor function to bridge between the AppAction + * interface and this derived interface. It is meant to be private + * and non-virtual as deriving from this class should only need to + * implement the observe function. + * + * For the Observer interface, this adaptor simply "applies" constantness + * to the arguments. + */ + void execute( + Teuchos::RCP > sh, + Teuchos::RCP > stepper, + const typename StepperForwardEulerAppAction::ACTION_LOCATION actLoc) + { this->observe(sh, stepper, actLoc); } + +public: + + /// Observe ForwardEuler Stepper. + virtual void observe( + Teuchos::RCP > /* sh */, + Teuchos::RCP > /* stepper */, + const typename StepperForwardEulerAppAction::ACTION_LOCATION actLoc) = 0; + +}; + +} // namespace Tempus + +#endif // Tempus_StepperForwardEulerObserverBase_hpp diff --git a/packages/tempus/src/Tempus_StepperForwardEulerObserverDefault.hpp b/packages/tempus/src/Tempus_StepperForwardEulerObserverDefault.hpp new file mode 100644 index 000000000000..952ab253837e --- /dev/null +++ b/packages/tempus/src/Tempus_StepperForwardEulerObserverDefault.hpp @@ -0,0 +1,60 @@ +// @HEADER +// **************************************************************************** +// Tempus: Copyright (2017) Sandia Corporation +// +// Distributed under BSD 3-clause license (See accompanying file Copyright.txt) +// **************************************************************************** +// @HEADER + +#ifndef Tempus_StepperForwardEulerObserverDefault_hpp +#define Tempus_StepperForwardEulerObserverDefault_hpp + +#include "Tempus_config.hpp" +#include "Tempus_SolutionHistory.hpp" +#include "Tempus_StepperForwardEulerObserverBase.hpp" + + +namespace Tempus { + +/** \brief Default observer for StepperForwardEuler. + * + * The default observer provides no-op functionality for the observer. + * See StepperForwardEulerObserverBase for details on the algorithm. + */ +template +class StepperForwardEulerObserverDefault + : virtual public Tempus::StepperForwardEulerObserverBase +{ +public: + + /// Constructor + StepperForwardEulerObserverDefault(){} + + /// Destructor + virtual ~StepperForwardEulerObserverDefault(){} + + /// Observe ForwardEuler Stepper at end of takeStep. + virtual void observe( + Teuchos::RCP > /* sh */, + Teuchos::RCP > /* stepper */, + const typename StepperForwardEulerAppAction::ACTION_LOCATION actLoc) + { + switch(actLoc) { + case StepperForwardEulerAppAction::BEGIN_STEP: + case StepperForwardEulerAppAction::BEFORE_EXPLICIT_EVAL: + case StepperForwardEulerAppAction::END_STEP: + { + // No-op. + break; + } + default: + TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, + "Error - unknown action location.\n"); + } + } + +}; + +} // namespace Tempus + +#endif // Tempus_StepperForwardEulerObserverDefault_hpp diff --git a/packages/tempus/src/Tempus_StepperForwardEuler_decl.hpp b/packages/tempus/src/Tempus_StepperForwardEuler_decl.hpp index dda049c938cc..1eda05bb68b8 100644 --- a/packages/tempus/src/Tempus_StepperForwardEuler_decl.hpp +++ b/packages/tempus/src/Tempus_StepperForwardEuler_decl.hpp @@ -11,8 +11,10 @@ #include "Tempus_config.hpp" #include "Tempus_StepperExplicit.hpp" -#include "Tempus_StepperForwardEulerObserver.hpp" - +#ifndef TEMPUS_HIDE_DEPRECATED_CODE + #include "Tempus_StepperForwardEulerObserver.hpp" +#endif +#include "Tempus_StepperForwardEulerAppAction.hpp" namespace Tempus { @@ -61,6 +63,7 @@ class StepperForwardEuler : virtual public Tempus::StepperExplicit */ StepperForwardEuler(); +#ifndef TEMPUS_HIDE_DEPRECATED_CODE /// Constructor StepperForwardEuler( const Teuchos::RCP >& appModel, @@ -68,7 +71,17 @@ class StepperForwardEuler : virtual public Tempus::StepperExplicit bool useFSAL, std::string ICConsistency, bool ICConsistencyCheck); +#endif + + /// Constructor + StepperForwardEuler( + const Teuchos::RCP >& appModel, + bool useFSAL, + std::string ICConsistency, + bool ICConsistencyCheck, + const Teuchos::RCP >& stepperFEAppAction); +#ifndef TEMPUS_HIDE_DEPRECATED_CODE /// \name Basic stepper methods //@{ virtual void setObserver( @@ -76,6 +89,13 @@ class StepperForwardEuler : virtual public Tempus::StepperExplicit virtual Teuchos::RCP > getObserver() const { return this->stepperFEObserver_; } +#endif + + virtual void setAppAction( + Teuchos::RCP > appAction); + + virtual Teuchos::RCP > getAppAction() const + { return stepperFEAppAction_; } /// Set the initial conditions, make them consistent, and set needed memory. virtual void setInitialConditions ( @@ -106,7 +126,11 @@ class StepperForwardEuler : virtual public Tempus::StepperExplicit protected: +#ifndef TEMPUS_HIDE_DEPRECATED_CODE Teuchos::RCP > stepperFEObserver_; +#endif + Teuchos::RCP > stepperFEAppAction_; + }; diff --git a/packages/tempus/src/Tempus_StepperForwardEuler_impl.hpp b/packages/tempus/src/Tempus_StepperForwardEuler_impl.hpp index 2a201e760569..562135252472 100644 --- a/packages/tempus/src/Tempus_StepperForwardEuler_impl.hpp +++ b/packages/tempus/src/Tempus_StepperForwardEuler_impl.hpp @@ -11,11 +11,10 @@ #include "Teuchos_VerboseObjectParameterListHelpers.hpp" #include "Thyra_VectorStdOps.hpp" - +#include "Tempus_StepperForwardEulerModifierDefault.hpp" namespace Tempus { - template StepperForwardEuler::StepperForwardEuler() { @@ -23,11 +22,13 @@ StepperForwardEuler::StepperForwardEuler() this->setUseFSAL( this->getUseFSALDefault()); this->setICConsistency( this->getICConsistencyDefault()); this->setICConsistencyCheck( this->getICConsistencyCheckDefault()); - +#ifndef TEMPUS_HIDE_DEPRECATED_CODE this->setObserver(); +#endif + this->setAppAction(Teuchos::null); } - +#ifndef TEMPUS_HIDE_DEPRECATED_CODE template StepperForwardEuler::StepperForwardEuler( const Teuchos::RCP >& appModel, @@ -40,16 +41,38 @@ StepperForwardEuler::StepperForwardEuler( this->setUseFSAL( useFSAL); this->setICConsistency( ICConsistency); this->setICConsistencyCheck( ICConsistencyCheck); - this->setObserver(obs); + this->setAppAction(Teuchos::null); if (appModel != Teuchos::null) { this->setModel(appModel); this->initialize(); } } +#endif +template +StepperForwardEuler::StepperForwardEuler( + const Teuchos::RCP >& appModel, + bool useFSAL, + std::string ICConsistency, + bool ICConsistencyCheck, + const Teuchos::RCP >& stepperFEAppAction) +{ + this->setStepperType( "Forward Euler"); + this->setUseFSAL( useFSAL); + this->setICConsistency( ICConsistency); + this->setICConsistencyCheck( ICConsistencyCheck); + this->setObserver(); + this->setAppAction(stepperFEAppAction); + if (appModel != Teuchos::null) { + this->setModel(appModel); + this->initialize(); + } +} + +#ifndef TEMPUS_HIDE_DEPRECATED_CODE template void StepperForwardEuler::setObserver( Teuchos::RCP > obs) @@ -71,6 +94,22 @@ void StepperForwardEuler::setObserver( this->isInitialized_ = false; } +#endif + +template +void StepperForwardEuler::setAppAction( + Teuchos::RCP > appAction) +{ + if (appAction == Teuchos::null) { + // Create default appAction + stepperFEAppAction_ = + Teuchos::rcp(new StepperForwardEulerModifierDefault()); + } + else { + stepperFEAppAction_ = appAction; + } +} + template void StepperForwardEuler::setInitialConditions( @@ -104,18 +143,26 @@ void StepperForwardEuler::takeStep( " Number of States = " << solutionHistory->getNumStates() << "\n" "Try setting in \"Solution History\" \"Storage Type\" = \"Undo\"\n" " or \"Storage Type\" = \"Static\" and \"Storage Limit\" = \"2\"\n"); - +#ifndef TEMPUS_HIDE_DEPRECATED_CODE this->stepperObserver_->observeBeginTakeStep(solutionHistory, *this); +#endif + RCP > thisStepper = Teuchos::rcpFromRef(*this); + stepperFEAppAction_->execute(solutionHistory, thisStepper, + StepperForwardEulerAppAction::ACTION_LOCATION::BEGIN_STEP); + RCP > currentState=solutionHistory->getCurrentState(); RCP > workingState=solutionHistory->getWorkingState(); - RCP > xDot = this->getStepperXDot(currentState); const Scalar dt = workingState->getTimeStep(); if ( !(this->getUseFSAL()) ) { // Need to compute XDotOld. +#ifndef TEMPUS_HIDE_DEPRECATED_CODE if (!Teuchos::is_null(stepperFEObserver_)) stepperFEObserver_->observeBeforeExplicit(solutionHistory, *this); +#endif + stepperFEAppAction_->execute(solutionHistory, thisStepper, + StepperForwardEulerAppAction::ACTION_LOCATION::BEFORE_EXPLICIT_EVAL); auto p = Teuchos::rcp(new ExplicitODEParameters(dt)); @@ -138,9 +185,13 @@ void StepperForwardEuler::takeStep( if (this->getUseFSAL()) { // Get consistent xDot^n. +#ifndef TEMPUS_HIDE_DEPRECATED_CODE if (!Teuchos::is_null(stepperFEObserver_)) stepperFEObserver_->observeBeforeExplicit(solutionHistory, *this); - +#endif + stepperFEAppAction_->execute(solutionHistory, thisStepper, + StepperForwardEulerAppAction::ACTION_LOCATION::BEFORE_EXPLICIT_EVAL); + auto p = Teuchos::rcp(new ExplicitODEParameters(dt)); // Evaluate xDot = f(x,t). @@ -158,7 +209,11 @@ void StepperForwardEuler::takeStep( workingState->setSolutionStatus(Status::PASSED); workingState->setOrder(this->getOrder()); workingState->computeNorms(currentState); +#ifndef TEMPUS_HIDE_DEPRECATED_CODE this->stepperObserver_->observeEndTakeStep(solutionHistory, *this); +#endif + stepperFEAppAction_->execute(solutionHistory, thisStepper, + StepperForwardEulerAppAction::ACTION_LOCATION::END_STEP); } return; } @@ -188,10 +243,14 @@ void StepperForwardEuler::describe( out << std::endl; Stepper::describe(out, verbLevel); StepperExplicit::describe(out, verbLevel); - +#ifndef TEMPUS_HIDE_DEPRECATED_CODE out << "--- StepperForwardEuler ---\n"; out << stepperFEObserver_ << std::endl; out << "---------------------------" << std::endl; +#endif + out << " stepperFEAppAction_ = " + << stepperFEAppAction_ << std::endl; + out << "----------------------------" << std::endl; } @@ -202,12 +261,16 @@ bool StepperForwardEuler::isValidSetup(Teuchos::FancyOStream & out) cons if ( !Stepper::isValidSetup(out) ) isValidSetup = false; if ( !StepperExplicit::isValidSetup(out) ) isValidSetup = false; - +#ifndef TEMPUS_HIDE_DEPRECATED_CODE if (stepperFEObserver_ == Teuchos::null) { isValidSetup = false; out << "The Forward Euler observer is not set!\n"; } - +#endif + if (stepperFEAppAction_ == Teuchos::null) { + isValidSetup = false; + out << "The Forward Euler AppAction is not set!\n"; + } return isValidSetup; } diff --git a/packages/tempus/src/Tempus_Stepper_decl.hpp b/packages/tempus/src/Tempus_Stepper_decl.hpp index 9343f21f2292..6c92d5febe4c 100644 --- a/packages/tempus/src/Tempus_Stepper_decl.hpp +++ b/packages/tempus/src/Tempus_Stepper_decl.hpp @@ -80,11 +80,10 @@ class Stepper getSolver() const = 0; /// Set Observer - virtual void setObserver( - Teuchos::RCP > obs = Teuchos::null) = 0; + virtual void setObserver(Teuchos::RCP > obs = Teuchos::null){} /// Get Observer - virtual Teuchos::RCP > getObserver() const = 0; + virtual Teuchos::RCP > getObserver() const {return Teuchos::null;} /// Initialize after construction and changing input parameters. virtual void initialize(); diff --git a/packages/tempus/unit_test/Tempus_UnitTest_ForwardEuler.cpp b/packages/tempus/unit_test/Tempus_UnitTest_ForwardEuler.cpp index dfff52a283d7..df9a95f93441 100644 --- a/packages/tempus/unit_test/Tempus_UnitTest_ForwardEuler.cpp +++ b/packages/tempus/unit_test/Tempus_UnitTest_ForwardEuler.cpp @@ -17,6 +17,11 @@ #include "Tempus_UnitTest_Utils.hpp" #include "Tempus_StepperRKButcherTableau.hpp" +#include "Tempus_StepperForwardEulerModifierBase.hpp" +#include "Tempus_StepperForwardEulerObserverBase.hpp" +#include "Tempus_StepperForwardEulerModifierXBase.hpp" +#include "Tempus_StepperForwardEulerModifierDefault.hpp" + #include "../TestModels/SinCosModel.hpp" #include "../TestModels/VanDerPolModel.hpp" #include "../TestUtils/Tempus_ConvergenceTestUtils.hpp" @@ -54,25 +59,31 @@ TEUCHOS_UNIT_TEST(ForwardEuler, Default_Construction) stepper->setModel(model); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized()); - // Default values for construction. - auto obs = rcp(new Tempus::StepperForwardEulerObserver()); - bool useFSAL = stepper->getUseFSALDefault(); std::string ICConsistency = stepper->getICConsistencyDefault(); bool ICConsistencyCheck = stepper->getICConsistencyCheckDefault(); // Test the set functions. +#ifndef TEMPUS_HIDE_DEPRECATED_CODE + auto obs = rcp(new Tempus::StepperForwardEulerObserver()); stepper->setObserver(obs); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized()); +#endif + auto modifier = rcp(new Tempus::StepperForwardEulerModifierDefault()); + stepper->setAppAction(modifier); stepper->setUseFSAL(useFSAL); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized()); stepper->setICConsistency(ICConsistency); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized()); stepper->setICConsistencyCheck(ICConsistencyCheck); stepper->initialize(); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized()); - +#ifndef TEMPUS_HIDE_DEPRECATED_CODE // Full argument list construction. stepper = rcp(new Tempus::StepperForwardEuler( - model, obs, useFSAL, ICConsistency, ICConsistencyCheck)); + model, obs, useFSAL, ICConsistency, ICConsistencyCheck)); TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized()); +#endif + stepper = rcp(new Tempus::StepperForwardEuler( + model, useFSAL, ICConsistency, ICConsistencyCheck,modifier)); + TEUCHOS_TEST_FOR_EXCEPT(!stepper->isInitialized()); } #endif // CONSTRUCTION @@ -89,4 +100,337 @@ TEUCHOS_UNIT_TEST(ForwardEuler, StepperFactory_Construction) #endif // STEPPERFACTORY_CONSTRUCTION +// ************************************************************ +// ************************************************************ +class StepperForwardEulerModifierTest + : virtual public Tempus::StepperForwardEulerModifierBase +{ +public: + + /// Constructor + StepperForwardEulerModifierTest() + : testBEGIN_STEP(false), testBEFORE_EXPLICIT_EVAL(false), + testEND_STEP(false), testCurrentValue(-0.99), testWorkingValue(-0.99), + testDt(-1.5), testType("") + {} + + /// Destructor + virtual ~StepperForwardEulerModifierTest(){} + + /// Observe ForwardEuler Stepper at end of takeStep. + virtual void modify( + Teuchos::RCP > sh, + Teuchos::RCP > stepper, + const typename Tempus::StepperForwardEulerAppAction::ACTION_LOCATION actLoc) + { + switch(actLoc) { + case StepperForwardEulerAppAction::BEGIN_STEP: + { + testBEGIN_STEP = true; + auto x = sh->getCurrentState()->getX(); + testCurrentValue = get_ele(*(x), 0); + break; + } + case StepperForwardEulerAppAction::BEFORE_EXPLICIT_EVAL: + { + testBEFORE_EXPLICIT_EVAL = true; + testDt = sh->getWorkingState()->getTimeStep()/10.0; + sh->getWorkingState()->setTimeStep(testDt); + testType = "Forward Euler - Modifier"; + stepper->setStepperType(testType); + break; + } + case StepperForwardEulerAppAction::END_STEP: + { + testEND_STEP = true; + auto x = sh->getWorkingState()->getX(); + testWorkingValue = get_ele(*(x), 0); + break; + } + default: + TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, + "Error - unknown action location.\n"); + } + } + bool testBEGIN_STEP; + bool testBEFORE_EXPLICIT_EVAL; + bool testEND_STEP; + double testCurrentValue; + double testWorkingValue; + double testDt; + std::string testType; +}; + +TEUCHOS_UNIT_TEST(ForwardEuler, AppAction_Modifier) +{ + auto model = rcp(new Tempus_Test::SinCosModel()); + + // Setup Stepper for field solve ---------------------------- + auto stepper = rcp(new Tempus::StepperForwardEuler()); + stepper->setModel(model); + auto modifier = rcp(new StepperForwardEulerModifierTest()); + stepper->setAppAction(modifier); + stepper->initialize(); + + // Setup initial condition SolutionState -------------------- + Thyra::ModelEvaluatorBase::InArgs inArgsIC = + stepper->getModel()->getNominalValues(); + auto icSolution = + rcp_const_cast > (inArgsIC.get_x()); + auto icState = rcp(new Tempus::SolutionState(icSolution)); + icState->setTime (0.0); + icState->setIndex (0); + icState->setTimeStep(0.0); + icState->setOrder (stepper->getOrder()); + icState->setSolutionStatus(Tempus::Status::PASSED); // ICs are passing. + + // Setup SolutionHistory ------------------------------------ + auto solutionHistory = rcp(new Tempus::SolutionHistory()); + solutionHistory->setName("Forward States"); + solutionHistory->setStorageType(Tempus::STORAGE_TYPE_STATIC); + solutionHistory->setStorageLimit(2); + solutionHistory->addState(icState); + + // Take one time step. + stepper->setInitialConditions(solutionHistory); + solutionHistory->initWorkingState(); + double dt = 0.1; + solutionHistory->getWorkingState()->setTimeStep(dt); + stepper->takeStep(solutionHistory); + + TEST_COMPARE(modifier->testBEGIN_STEP, ==, true); + TEST_COMPARE(modifier->testBEFORE_EXPLICIT_EVAL, ==, true); + TEST_COMPARE(modifier->testEND_STEP, ==, true); + + auto x = solutionHistory->getCurrentState()->getX(); + TEST_FLOATING_EQUALITY(modifier->testCurrentValue, get_ele(*(x), 0), 1.0e-15); + x = solutionHistory->getWorkingState()->getX(); + TEST_FLOATING_EQUALITY(modifier->testWorkingValue, get_ele(*(x), 0), 1.0e-15); + auto Dt = solutionHistory->getWorkingState()->getTimeStep(); + TEST_FLOATING_EQUALITY(modifier->testDt, Dt, 1.0e-15); + + TEST_COMPARE(modifier->testType, ==, "Forward Euler - Modifier"); +} + + // ************************************************************ + // ************************************************************ +class StepperForwardEulerObserverTest + : virtual public Tempus::StepperForwardEulerObserverBase +{ +public: + + /// Constructor + StepperForwardEulerObserverTest() + : testBEGIN_STEP(false), testBEFORE_EXPLICIT_EVAL(false), + testEND_STEP(false), testCurrentValue(-0.99), + testWorkingValue(-0.99),testDt(-1.5), testType("") + {} + + /// Destructor + virtual ~StepperForwardEulerObserverTest(){} + + /// Observe ForwardEuler Stepper at end of takeStep. + virtual void observe( + Teuchos::RCP > sh, + Teuchos::RCP > stepper, + const typename Tempus::StepperForwardEulerAppAction::ACTION_LOCATION actLoc) + { + switch(actLoc) { + case StepperForwardEulerAppAction::BEGIN_STEP: + { + testBEGIN_STEP = true; + auto x = sh->getCurrentState()->getX(); + testCurrentValue = get_ele(*(x), 0); + break; + } + case StepperForwardEulerAppAction::BEFORE_EXPLICIT_EVAL: + { + testBEFORE_EXPLICIT_EVAL = true; + testDt = sh->getWorkingState()->getTimeStep(); + testType = stepper->getStepperType(); + break; + } + case StepperForwardEulerAppAction::END_STEP: + { + testEND_STEP = true; + auto x = sh->getWorkingState()->getX(); + testWorkingValue = get_ele(*(x), 0); + break; + } + default: + TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, + "Error - unknown action location.\n"); + } + } + + bool testBEGIN_STEP; + bool testBEFORE_EXPLICIT_EVAL; + bool testEND_STEP; + double testCurrentValue; + double testWorkingValue; + double testDt; + std::string testType; +}; + + TEUCHOS_UNIT_TEST(ForwardEuler, AppAction_Observer) + { + auto model = rcp(new Tempus_Test::SinCosModel()); + + // Setup Stepper for field solve ---------------------------- + auto stepper = rcp(new Tempus::StepperForwardEuler()); + stepper->setModel(model); + auto observer = rcp(new StepperForwardEulerObserverTest()); + stepper->setAppAction(observer); + stepper->initialize(); + + // Setup initial condition SolutionState -------------------- + Thyra::ModelEvaluatorBase::InArgs inArgsIC = + stepper->getModel()->getNominalValues(); + auto icSolution = + rcp_const_cast > (inArgsIC.get_x()); + auto icState = rcp(new Tempus::SolutionState(icSolution)); + icState->setTime (0.0); + icState->setIndex (0); + icState->setTimeStep(0.0); + icState->setOrder (stepper->getOrder()); + icState->setSolutionStatus(Tempus::Status::PASSED); // ICs are passing. + + // Setup SolutionHistory ------------------------------------ + auto solutionHistory = rcp(new Tempus::SolutionHistory()); + solutionHistory->setName("Forward States"); + solutionHistory->setStorageType(Tempus::STORAGE_TYPE_STATIC); + solutionHistory->setStorageLimit(2); + solutionHistory->addState(icState); + + // Take one time step. + stepper->setInitialConditions(solutionHistory); + solutionHistory->initWorkingState(); + double dt = 0.1; + solutionHistory->getWorkingState()->setTimeStep(dt); + stepper->takeStep(solutionHistory); + + TEST_COMPARE(observer->testBEGIN_STEP, ==, true); + TEST_COMPARE(observer->testBEFORE_EXPLICIT_EVAL, ==, true); + TEST_COMPARE(observer->testEND_STEP, ==, true); + + auto x = solutionHistory->getCurrentState()->getX(); + TEST_FLOATING_EQUALITY(observer->testCurrentValue, get_ele(*(x), 0), 1.0e-15); + x = solutionHistory->getWorkingState()->getX(); + TEST_FLOATING_EQUALITY(observer->testWorkingValue, get_ele(*(x), 0), 1.0e-15); + TEST_FLOATING_EQUALITY(observer->testDt, dt, 1.0e-15); + + TEST_COMPARE(observer->testType, ==, "Forward Euler"); +} + + // ************************************************************ + // ************************************************************ +class StepperForwardEulerModifierXTest + : virtual public Tempus::StepperForwardEulerModifierXBase +{ +public: + + /// Constructor + StepperForwardEulerModifierXTest() + : testX_BEGIN_STEP(false), testX_BEFORE_EXPLICIT_EVAL(false), + testXDOT_END_STEP(false), testX(-0.99), + testXDot(-0.99), testDt(-1.5), testTime(-1.5) + {} + + /// Destructor + virtual ~StepperForwardEulerModifierXTest(){} + + /// Observe BackwardEuler Stepper at end of takeStep. + virtual void modify( + Teuchos::RCP > x, + const double time, const double dt, + const typename Tempus::StepperForwardEulerModifierXBase::MODIFIER_TYPE modType) + { + switch(modType) { + case StepperForwardEulerModifierXBase::X_BEGIN_STEP: + { + testX_BEGIN_STEP = true; + testX = get_ele(*(x), 0); + break; + } + case StepperForwardEulerModifierXBase::X_BEFORE_EXPLICIT_EVAL: + { + testX_BEFORE_EXPLICIT_EVAL = true; + testDt = dt; + testTime = time; + break; + } + case StepperForwardEulerModifierXBase::XDOT_END_STEP: + { + testXDOT_END_STEP = true; + testXDot = get_ele(*(x), 0); + break; + } + default: + TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, + "Error - unknown action location.\n"); + } + } + bool testX_BEGIN_STEP; + bool testX_BEFORE_EXPLICIT_EVAL; + bool testXDOT_END_STEP; + double testX; + double testXDot; + double testDt; + double testTime; +}; + + TEUCHOS_UNIT_TEST(ForwardEuler, AppAction_ModifierX) + { + auto model = rcp(new Tempus_Test::SinCosModel()); + + // Setup Stepper for field solve ---------------------------- + auto stepper = rcp(new Tempus::StepperForwardEuler()); + stepper->setModel(model); + auto modifierX = rcp(new StepperForwardEulerModifierXTest()); + stepper->setAppAction(modifierX); + stepper->initialize(); + + // Setup initial condition SolutionState -------------------- + Thyra::ModelEvaluatorBase::InArgs inArgsIC = + stepper->getModel()->getNominalValues(); + auto icSolution = + rcp_const_cast > (inArgsIC.get_x()); + auto icState = rcp(new Tempus::SolutionState(icSolution)); + icState->setTime (0.0); + icState->setIndex (0); + icState->setTimeStep(0.0); + icState->setOrder (stepper->getOrder()); + icState->setSolutionStatus(Tempus::Status::PASSED); // ICs are passing. + + // Setup SolutionHistory ------------------------------------ + auto solutionHistory = rcp(new Tempus::SolutionHistory()); + solutionHistory->setName("Forward States"); + solutionHistory->setStorageType(Tempus::STORAGE_TYPE_STATIC); + solutionHistory->setStorageLimit(2); + solutionHistory->addState(icState); + + // Take one time step. + stepper->setInitialConditions(solutionHistory); + solutionHistory->initWorkingState(); + double dt = 0.1; + solutionHistory->getWorkingState()->setTimeStep(dt); + stepper->takeStep(solutionHistory); + + TEST_COMPARE(modifierX->testX_BEGIN_STEP, ==, true); + TEST_COMPARE(modifierX->testX_BEFORE_EXPLICIT_EVAL, ==, true); + TEST_COMPARE(modifierX->testXDOT_END_STEP, ==, true); + + auto x = solutionHistory->getCurrentState()->getX(); + TEST_FLOATING_EQUALITY(modifierX->testX, get_ele(*(x), 0), 1.0e-15); + // Temperary memory for xDot is not guarranteed to exist outside the Stepper. + auto xDot = stepper->getStepperXDot(solutionHistory->getWorkingState()); + TEST_FLOATING_EQUALITY(modifierX->testXDot, get_ele(*(xDot), 0),1.0e-15); + auto Dt = solutionHistory->getWorkingState()->getTimeStep(); + TEST_FLOATING_EQUALITY(modifierX->testDt, Dt, 1.0e-15); + + auto time = solutionHistory->getWorkingState()->getTime(); + TEST_FLOATING_EQUALITY(modifierX->testTime, time, 1.0e-15); + } + } // namespace Tempus_Test + diff --git a/packages/teuchos/core/src/Teuchos_ScalarTraits.hpp b/packages/teuchos/core/src/Teuchos_ScalarTraits.hpp index 38d994fea0a4..a30269a3b5dc 100644 --- a/packages/teuchos/core/src/Teuchos_ScalarTraits.hpp +++ b/packages/teuchos/core/src/Teuchos_ScalarTraits.hpp @@ -635,7 +635,7 @@ struct ScalarTraits #ifdef __sun return 0.0f/std::sin(0.0f); #else - return flt_nan; + return std::numeric_limits::quiet_NaN(); #endif } static inline bool isnaninf(float x) { @@ -748,7 +748,7 @@ struct ScalarTraits #ifdef __sun return 0.0/std::sin(0.0); #else - return dbl_nan; + return std::numeric_limits::quiet_NaN(); #endif } static inline bool isnaninf(double x) { diff --git a/packages/thyra/core/src/support/nonlinear/model_evaluator/client_support/Thyra_ModelEvaluatorDelegatorBase.hpp b/packages/thyra/core/src/support/nonlinear/model_evaluator/client_support/Thyra_ModelEvaluatorDelegatorBase.hpp index 91e3ad4c5b75..5f3dd6accf1a 100644 --- a/packages/thyra/core/src/support/nonlinear/model_evaluator/client_support/Thyra_ModelEvaluatorDelegatorBase.hpp +++ b/packages/thyra/core/src/support/nonlinear/model_evaluator/client_support/Thyra_ModelEvaluatorDelegatorBase.hpp @@ -504,7 +504,7 @@ ModelEvaluatorDelegatorBase::createInArgs() const { ModelEvaluatorBase::InArgsSetup inArgs = getUnderlyingModel()->createInArgs(); inArgs.setModelEvalDescription(this->description()); - return inArgs; + return std::move(inArgs); } @@ -608,7 +608,7 @@ ModelEvaluatorDelegatorBase::createOutArgsImpl() const ModelEvaluatorBase::OutArgsSetup outArgs = getUnderlyingModel()->createOutArgs(); outArgs.setModelEvalDescription(this->description()); - return outArgs; + return std::move(outArgs); }