9 #ifndef TEMPUS_TEST_HARMONIC_OSCILLATOR_MODEL_IMPL_HPP 
   10 #define TEMPUS_TEST_HARMONIC_OSCILLATOR_MODEL_IMPL_HPP 
   12 #include "Teuchos_StandardParameterEntryValidators.hpp" 
   14 #include "Thyra_DefaultSpmdVectorSpace.hpp" 
   15 #include "Thyra_DetachedVectorView.hpp" 
   16 #include "Thyra_DetachedMultiVectorView.hpp" 
   17 #include "Thyra_DefaultSerialDenseLinearOpWithSolveFactory.hpp" 
   18 #include "Thyra_DefaultMultiVectorLinearOpWithSolve.hpp" 
   19 #include "Thyra_DefaultLinearOpSource.hpp" 
   20 #include "Thyra_VectorStdOps.hpp" 
   24 namespace Tempus_Test {
 
   26 template<
class Scalar>
 
   29  out_(Teuchos::VerboseObjectBase::getDefaultOStream())
 
   33   *
out_ << 
"\n\nDamping coeff c = " << 
c_ << 
"\n";
 
   34   *
out_ << 
"Forcing coeff f = " << 
f_ << 
"\n";
 
   35   *
out_ << 
"x coeff k = " << 
k_ << 
"\n";
 
   36   *
out_ << 
"Mass coeff m = " << 
m_ << 
"\n";
 
   46   Thyra::put_scalar(0.0, x_vec_.ptr());
 
   48   Thyra::put_scalar(1.0, x_dot_vec_.ptr());
 
   55   if (use_accel_IC == 
true) {
 
   56     Thyra::put_scalar(-2.0, x_dot_dot_vec_.ptr());
 
   61     Thyra::put_scalar(7.0, x_dot_dot_vec_.ptr());
 
   71 template<
class Scalar>
 
   72 Thyra::ModelEvaluatorBase::InArgs<Scalar>
 
   76   using Thyra::VectorBase;
 
   77   TEUCHOS_TEST_FOR_EXCEPTION( !isInitialized_, std::logic_error,
 
   78       "Error, setupInOutArgs_ must be called first!\n");
 
   79   Thyra::ModelEvaluatorBase::InArgs<Scalar> inArgs = inArgs_;
 
   81   inArgs.set_t(exact_t);
 
   82   Teuchos::RCP<VectorBase<Scalar> > exact_x = createMember(x_space_);
 
   84     Thyra::DetachedVectorView<Scalar> exact_x_view(*exact_x);
 
   87         exact_x_view[0] = t*(1.0+0.5*f_*t);
 
   89         exact_x_view[0] = (c_-f_)/(c_*c_)*(1.0-exp(-c_*t))
 
   93       exact_x_view[0] = 1.0/sqrt(k_)*sin(sqrt(k_)*t) + f_/k_*(1.0-cos(sqrt(k_)*t));
 
   96   inArgs.set_x(exact_x);
 
   97   Teuchos::RCP<VectorBase<Scalar> > exact_x_dot = createMember(x_space_);
 
   99     Thyra::DetachedVectorView<Scalar> exact_x_dot_view(*exact_x_dot);
 
  102         exact_x_dot_view[0] = 1.0+f_*t;
 
  104         exact_x_dot_view[0] = (c_-f_)/c_*exp(-c_*t)+f_/c_;
 
  107       exact_x_dot_view[0] = cos(sqrt(k_)*t) + f_/sqrt(k_)*sin(sqrt(k_)*t);
 
  110   inArgs.set_x_dot(exact_x_dot);
 
  111   Teuchos::RCP<VectorBase<Scalar> > exact_x_dot_dot = createMember(x_space_);
 
  113     Thyra::DetachedVectorView<Scalar> exact_x_dot_dot_view(*exact_x_dot_dot);
 
  116         exact_x_dot_dot_view[0] = f_;
 
  118         exact_x_dot_dot_view[0] = (f_-c_)*exp(-c_*t);
 
  121       exact_x_dot_dot_view[0] = f_*cos(sqrt(k_)*t) - sqrt(k_)*sin(sqrt(k_)*t);
 
  124   inArgs.set_x_dot_dot(exact_x_dot_dot);
 
  128 template<
class Scalar>
 
  129 Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar> >
 
  137 template<
class Scalar>
 
  138 Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar> >
 
  146 template<
class Scalar>
 
  147 Thyra::ModelEvaluatorBase::InArgs<Scalar>
 
  151   TEUCHOS_TEST_FOR_EXCEPTION( !isInitialized_, std::logic_error,
 
  152       "Error, setupInOutArgs_ must be called first!\n");
 
  153   return nominalValues_;
 
  157 template<
class Scalar>
 
  158 Teuchos::RCP<Thyra::LinearOpWithSolveBase<Scalar> >
 
  162   Teuchos::RCP<const Thyra::LinearOpWithSolveFactoryBase<Scalar> > W_factory = this->get_W_factory();
 
  163   Teuchos::RCP<Thyra::LinearOpBase<Scalar> > matrix = this->create_W_op();
 
  164   Teuchos::RCP<Thyra::MultiVectorBase<Scalar> > matrix_mv = Teuchos::rcp_dynamic_cast<Thyra::MultiVectorBase<Scalar> >(matrix,
true);
 
  165   Thyra::DetachedMultiVectorView<Scalar> matrix_view( *matrix_mv );
 
  167   matrix_view(0,0) = 1.0;
 
  168   Teuchos::RCP<Thyra::LinearOpWithSolveBase<Scalar> > W =
 
  169     Thyra::linearOpWithSolve<Scalar>(*W_factory, matrix );
 
  174 template<
class Scalar>
 
  175 Teuchos::RCP<Thyra::LinearOpBase<Scalar> >
 
  179   Teuchos::RCP<Thyra::MultiVectorBase<Scalar> > matrix = Thyra::createMembers(x_space_, vecLength_);
 
  184 template<
class Scalar>
 
  185 Teuchos::RCP<const Thyra::LinearOpWithSolveFactoryBase<Scalar> >
 
  189   Teuchos::RCP<Thyra::LinearOpWithSolveFactoryBase<Scalar> > W_factory =
 
  190     Thyra::defaultSerialDenseLinearOpWithSolveFactory<Scalar>();
 
  195 template<
class Scalar>
 
  196 Thyra::ModelEvaluatorBase::InArgs<Scalar>
 
  208 template<
class Scalar>
 
  209 Thyra::ModelEvaluatorBase::OutArgs<Scalar>
 
  218 template<
class Scalar>
 
  222   const Thyra::ModelEvaluatorBase::InArgs<Scalar> &inArgs,
 
  223   const Thyra::ModelEvaluatorBase::OutArgs<Scalar> &outArgs
 
  227   using Thyra::VectorBase;
 
  228   TEUCHOS_TEST_FOR_EXCEPTION( !isInitialized_, std::logic_error,
 
  229       "Error, setupInOutArgs_ must be called first!\n");
 
  231   RCP<const VectorBase<Scalar> > x_in = inArgs.get_x();
 
  232   double beta = inArgs.get_beta();
 
  234     TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
 
  235       "\n ERROR: HarmonicOscillatorModel requires x as InArgs.\n");
 
  237   Thyra::ConstDetachedVectorView<Scalar> x_in_view( *x_in );
 
  239   auto myVecLength  = x_in_view.subDim();
 
  241   RCP<const VectorBase<Scalar> > x_dot_in = inArgs.get_x_dot();
 
  242   double alpha = inArgs.get_alpha();
 
  244   RCP<const VectorBase<Scalar> > x_dotdot_in = inArgs.get_x_dot_dot();
 
  245   double omega = inArgs.get_W_x_dot_dot_coeff();
 
  248   RCP<VectorBase<Scalar> > f_out = outArgs.get_f();
 
  249   RCP<VectorBase<Scalar> > g_out = outArgs.get_g(0);
 
  250   const RCP<Thyra::LinearOpBase<Scalar> > W_out = outArgs.get_W_op();
 
  252   Scalar neg_sign = 1.0;
 
  254   if (inArgs.get_x_dot_dot().is_null()) neg_sign = -1.0;
 
  257   if (f_out != Teuchos::null) {
 
  258     Thyra::DetachedVectorView<Scalar> f_out_view( *f_out );
 
  259     for (
int i=0; i<myVecLength; i++) {
 
  262     if (x_dotdot_in != Teuchos::null) {
 
  263       Thyra::ConstDetachedVectorView<Scalar> x_dotdot_in_view( *x_dotdot_in);
 
  264       for (
int i=0; i<myVecLength; i++) {
 
  265         f_out_view[i] = x_dotdot_in_view[i] - f_out_view[i];
 
  268     if (x_dot_in != Teuchos::null) {
 
  269       Thyra::ConstDetachedVectorView<Scalar> x_dot_in_view( *x_dot_in);
 
  270       for (
int i=0; i<myVecLength; i++) {
 
  271         f_out_view[i] += neg_sign*c_*x_dot_in_view[i];
 
  274     if (x_in != Teuchos::null) {
 
  275       for (
int i=0; i<myVecLength; i++) {
 
  276         f_out_view[i] += neg_sign*k_*x_in_view[i];
 
  282   if (W_out != Teuchos::null) {
 
  283     RCP<Thyra::MultiVectorBase<Scalar> > matrix = Teuchos::rcp_dynamic_cast<Thyra::MultiVectorBase<Scalar> >(W_out,
true);
 
  284     Thyra::DetachedMultiVectorView<Scalar> matrix_view( *matrix );
 
  286       TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
 
  287         "\n ERROR: omega = 0 in HarmonicOscillatorModel!\n");
 
  289     matrix_view(0,0) = omega;
 
  290     if (x_dot_in != Teuchos::null) {
 
  291       matrix_view(0,0) += neg_sign*c_*alpha;
 
  293     if (x_in != Teuchos::null) {
 
  294       matrix_view(0,0) += neg_sign*k_*beta;
 
  300   if (g_out != Teuchos::null) {
 
  301     Thyra::DetachedVectorView<Scalar> g_out_view(*g_out);
 
  302     g_out_view[0] = Thyra::sum(*x_in)/vecLength_;
 
  306 template<
class Scalar>
 
  307 Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar> >
 
  311   TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
 
  312                      "\n Error!  HarmonicOscillatorModel::get_p_space() is not supported!\n");
 
  313   return Teuchos::null;
 
  316 template<
class Scalar>
 
  317 Teuchos::RCP<const Teuchos::Array<std::string> >
 
  321   TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
 
  322                      "\n Error!  HarmonicOscillatorModel::get_p_names() is not supported!\n");
 
  323   return Teuchos::null;
 
  326 template<
class Scalar>
 
  327 Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar> >
 
  331   TEUCHOS_TEST_FOR_EXCEPTION(j != 0, std::logic_error,
 
  332                      "\n Error!  HarmonicOscillatorModel::get_g_space() only " <<
 
  333                      " supports 1 parameter vector.  Supplied index l = " <<
 
  340 template<
class Scalar>
 
  345   if (isInitialized_) 
return;
 
  348   Thyra::ModelEvaluatorBase::InArgsSetup<Scalar> inArgs;
 
  349   inArgs.setModelEvalDescription(this->description());
 
  351   inArgs.setSupports(Thyra::ModelEvaluatorBase::IN_ARG_x);
 
  352   inArgs.setSupports(Thyra::ModelEvaluatorBase::IN_ARG_x_dot);
 
  353   inArgs.setSupports(Thyra::ModelEvaluatorBase::IN_ARG_x_dot_dot);
 
  354   inArgs.setSupports(Thyra::ModelEvaluatorBase::IN_ARG_t);
 
  355   inArgs.setSupports(Thyra::ModelEvaluatorBase::IN_ARG_W_x_dot_dot_coeff);
 
  356   inArgs.setSupports(Thyra::ModelEvaluatorBase::IN_ARG_alpha);
 
  357   inArgs.setSupports(Thyra::ModelEvaluatorBase::IN_ARG_beta);
 
  361   Thyra::ModelEvaluatorBase::OutArgsSetup<Scalar> outArgs;
 
  362   outArgs.setModelEvalDescription(this->description());
 
  363   outArgs.set_Np_Ng(0, numResponses_);
 
  365   outArgs.setSupports(Thyra::ModelEvaluatorBase::OUT_ARG_f);
 
  366   outArgs.setSupports(Thyra::ModelEvaluatorBase::OUT_ARG_W_op);
 
  374   nominalValues_ = inArgs_;
 
  375   nominalValues_.set_t(0.0);
 
  376   nominalValues_.set_x(x_vec_);
 
  377   nominalValues_.set_x_dot(x_dot_vec_);
 
  378   nominalValues_.set_x_dot_dot(x_dot_dot_vec_);
 
  380   isInitialized_ = 
true;
 
  384 template<
class Scalar>
 
  391   using Teuchos::ParameterList;
 
  392   RCP<ParameterList> tmpPL = Teuchos::rcp(
new ParameterList(
"HarmonicOscillatorModel"));
 
  393   if (paramList != Teuchos::null) tmpPL = paramList;
 
  394   tmpPL->validateParametersAndSetDefaults(*this->getValidParameters());
 
  395   this->setMyParamList(tmpPL);
 
  396   RCP<ParameterList> pl = this->getMyNonconstParamList();
 
  397   c_ = get<Scalar>(*pl,
"Damping coeff c");
 
  398   f_ = get<Scalar>(*pl,
"Forcing coeff f");
 
  399   k_ = get<Scalar>(*pl,
"x coeff k");
 
  400   m_ = get<Scalar>(*pl,
"Mass coeff m");
 
  402     TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
 
  403       "Error: invalid value of Mass coeff m = " << m_ <<
"!  Mass coeff m must be > 0.\n");
 
  406     TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
 
  407       "Error: invalid value of x coeff k = " << k_ <<
"!  x coeff k must be >= 0.\n");
 
  409   if ((k_ > 0.0) && (c_ != 0.0)) {
 
  410     TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
 
  411       "Error: HarmonicOscillator model only supports x coeff k > 0 when Damping coeff c = 0.  You have " 
  412       << 
"specified x coeff k = " << k_ << 
" and Damping coeff c = " << c_ << 
".\n");
 
  416 template<
class Scalar>
 
  417 Teuchos::RCP<const Teuchos::ParameterList>
 
  421   static Teuchos::RCP<const Teuchos::ParameterList> validPL;
 
  422   if (is_null(validPL)) {
 
  423     Teuchos::RCP<Teuchos::ParameterList> pl = Teuchos::parameterList();
 
  425     Teuchos::setDoubleParameter(
 
  426         "Damping coeff c", 0.0, 
"Damping coefficient in model", &*pl);
 
  427     Teuchos::setDoubleParameter(
 
  428         "Forcing coeff f", -1.0, 
"Forcing coefficient in model", &*pl);
 
  429     Teuchos::setDoubleParameter(
 
  430         "x coeff k", 0.0, 
"x coefficient in model", &*pl);
 
  431     Teuchos::setDoubleParameter(
 
  432         "Mass coeff m", 1.0, 
"Mass coefficient in model", &*pl);
 
  438 #endif // TEMPUS_TEST_HARMONIC_OSCILLATOR_MODEL_IMPL_HPP 
Thyra::ModelEvaluatorBase::InArgs< Scalar > getNominalValues() const 
 
Thyra::ModelEvaluatorBase::OutArgs< Scalar > createOutArgsImpl() const 
 
Teuchos::RCP< Thyra::VectorBase< Scalar > > x_dot_vec_
 
Teuchos::RCP< const Thyra::VectorSpaceBase< Scalar > > g_space_
 
Teuchos::RCP< const Thyra::LinearOpWithSolveFactoryBase< Scalar > > get_W_factory() const 
 
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const 
 
Teuchos::RCP< const Teuchos::Array< std::string > > get_p_names(int l) const 
 
Thyra::ModelEvaluatorBase::InArgs< Scalar > getExactSolution(double t) const 
 
void evalModelImpl(const Thyra::ModelEvaluatorBase::InArgs< Scalar > &inArgs_bar, const Thyra::ModelEvaluatorBase::OutArgs< Scalar > &outArgs_bar) const 
 
Teuchos::RCP< const Thyra::VectorSpaceBase< Scalar > > get_x_space() const 
 
Teuchos::RCP< const Thyra::VectorSpaceBase< Scalar > > get_g_space(int j) const 
 
Teuchos::RCP< Teuchos::FancyOStream > out_
 
Teuchos::RCP< Thyra::VectorBase< Scalar > > x_dot_dot_vec_
 
Teuchos::RCP< const Thyra::VectorSpaceBase< Scalar > > get_p_space(int l) const 
 
Teuchos::RCP< Thyra::LinearOpWithSolveBase< Scalar > > create_W() const 
 
void setParameterList(Teuchos::RCP< Teuchos::ParameterList > const ¶mList)
 
Teuchos::RCP< const Thyra::VectorSpaceBase< Scalar > > x_space_
 
Teuchos::RCP< Thyra::LinearOpBase< Scalar > > create_W_op() const 
 
HarmonicOscillatorModel(Teuchos::RCP< Teuchos::ParameterList > pList=Teuchos::null, const bool use_accel_IC=false)
 
Teuchos::RCP< Thyra::VectorBase< Scalar > > x_vec_
 
void setupInOutArgs_() const 
 
Thyra::ModelEvaluatorBase::InArgs< Scalar > createInArgs() const 
 
Teuchos::RCP< const Thyra::VectorSpaceBase< Scalar > > get_f_space() const