9 #ifndef TEMPUS_TEST_SINCOS_MODEL_IMPL_HPP
10 #define TEMPUS_TEST_SINCOS_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"
21 #include "Thyra_MultiVectorStdOps.hpp"
22 #include "Thyra_DefaultMultiVectorProductVector.hpp"
26 namespace Tempus_Test {
28 template <
class Scalar>
31 isInitialized_ =
false;
37 acceptModelParams_ =
false;
38 useDfDpAsTangent_ =
false;
48 x_space_ = Thyra::defaultSpmdVectorSpace<Scalar>(dim_);
49 f_space_ = Thyra::defaultSpmdVectorSpace<Scalar>(dim_);
51 p_space_ = Thyra::defaultSpmdVectorSpace<Scalar>(np_);
52 g_space_ = Thyra::defaultSpmdVectorSpace<Scalar>(ng_);
54 setParameterList(pList_);
57 DxDp_space_ = Thyra::multiVectorProductVectorSpace(x_space_, np_);
60 template <
class Scalar>
65 "Error, setupInOutArgs_ must be called first!\n");
68 inArgs.
set_t(exact_t);
72 exact_x_view[0] = a_ + b_ * sin((f_ / L_) * t + phi_);
73 exact_x_view[1] = b_ * (f_ / L_) * cos((f_ / L_) * t + phi_);
75 inArgs.
set_x(exact_x);
79 exact_x_dot_view[0] = b_ * (f_ / L_) * cos((f_ / L_) * t + phi_);
81 -b_ * (f_ / L_) * (f_ / L_) * sin((f_ / L_) * t + phi_);
95 template <
class Scalar>
100 "Error, setupInOutArgs_ must be called first!\n");
102 if (!acceptModelParams_) {
111 inArgs.
set_t(exact_t);
116 exact_s_view[0] = 1.0;
117 exact_s_view[1] = 0.0;
120 exact_s_view[0] = (b / L) * t * cos((f / L) * t + phi);
121 exact_s_view[1] = (b / L) * cos((f / L) * t + phi) -
122 (b * f * t / (L * L)) * sin((f / L) * t + phi);
125 exact_s_view[0] = -(b * f * t / (L * L)) * cos((f / L) * t + phi);
126 exact_s_view[1] = -(b * f / (L * L)) * cos((f / L) * t + phi) +
127 (b * f * f * t / (L * L * L)) * sin((f / L) * t + phi);
130 inArgs.
set_x(exact_s);
135 exact_s_dot_view[0] = 0.0;
136 exact_s_dot_view[1] = 0.0;
139 exact_s_dot_view[0] = (b / L) * cos((f / L) * t + phi) -
140 (b * f * t / (L * L)) * sin((f / L) * t + phi);
141 exact_s_dot_view[1] =
142 -(2.0 * b * f / (L * L)) * sin((f / L) * t + phi) -
143 (b * f * f * t / (L * L * L)) * cos((f / L) * t + phi);
146 exact_s_dot_view[0] =
147 -(b * f / (L * L)) * cos((f / L) * t + phi) +
148 (b * f * f * t / (L * L * L)) * sin((f / L) * t + phi);
149 exact_s_dot_view[1] =
150 (2.0 * b * f * f / (L * L * L)) * sin((f / L) * t + phi) +
151 (b * f * f * f * t / (L * L * L * L)) * cos((f / L) * t + phi);
158 template <
class Scalar>
165 template <
class Scalar>
172 template <
class Scalar>
177 "Error, setupInOutArgs_ must be called first!\n");
178 return nominalValues_;
181 template <
class Scalar>
187 this->get_W_factory();
205 V_V(multivec->col(0).
ptr(), *vec);
211 V_V(multivec->col(1).
ptr(), *vec);
215 Thyra::linearOpWithSolve<Scalar>(*W_factory, matrix);
225 template <
class Scalar>
230 Thyra::createMembers(x_space_, dim_);
234 template <
class Scalar>
239 Thyra::defaultSerialDenseLinearOpWithSolveFactory<Scalar>();
254 template <
class Scalar>
264 template <
class Scalar>
272 template <
class Scalar>
279 using Teuchos::rcp_dynamic_cast;
283 "Error, setupInOutArgs_ must be called first!\n");
292 if (acceptModelParams_) {
294 inArgs.
get_p(0).assert_not_null();
302 if (acceptModelParams_) {
303 if (inArgs.
get_p(1) != Teuchos::null)
305 rcp_dynamic_cast<const DMVPV>(inArgs.
get_p(1))->getMultiVector();
306 if (inArgs.
get_p(2) != Teuchos::null)
308 rcp_dynamic_cast<const DMVPV>(inArgs.
get_p(2))->getMultiVector();
316 if (acceptModelParams_) {
325 f_out_view[0] = x_in_view[1];
326 f_out_view[1] = (f / L) * (f / L) * (a - x_in_view[0]);
333 matrix_view(0, 0) = 0.0;
334 matrix_view(0, 1) = +beta;
335 matrix_view(1, 0) = -beta * (f / L) * (f / L);
336 matrix_view(1, 1) = 0.0;
341 DfDp_out_view(0, 0) = 0.0;
342 DfDp_out_view(0, 1) = 0.0;
343 DfDp_out_view(0, 2) = 0.0;
344 DfDp_out_view(1, 0) = (f / L) * (f / L);
345 DfDp_out_view(1, 1) = (2.0 * f / (L * L)) * (a - x_in_view[0]);
346 DfDp_out_view(1, 2) = -(2.0 * f * f / (L * L * L)) * (a - x_in_view[0]);
349 if (useDfDpAsTangent_ && !
is_null(DxDp_in)) {
351 DfDp_out_view(0, 0) += DxDp(1, 0);
352 DfDp_out_view(0, 1) += DxDp(1, 1);
353 DfDp_out_view(0, 2) += DxDp(1, 2);
354 DfDp_out_view(1, 0) += -(f / L) * (f / L) * DxDp(0, 0);
355 DfDp_out_view(1, 1) += -(f / L) * (f / L) * DxDp(0, 1);
356 DfDp_out_view(1, 2) += -(f / L) * (f / L) * DxDp(0, 2);
363 x_dot_in = inArgs.
get_x_dot().assert_not_null();
368 f_out_view[0] = x_dot_in_view[0] - x_in_view[1];
369 f_out_view[1] = x_dot_in_view[1] - (f / L) * (f / L) * (a - x_in_view[0]);
376 matrix_view(0, 0) = alpha;
377 matrix_view(0, 1) = -beta;
378 matrix_view(1, 0) = +beta * (f / L) * (f / L);
379 matrix_view(1, 1) = alpha;
384 DfDp_out_view(0, 0) = 0.0;
385 DfDp_out_view(0, 1) = 0.0;
386 DfDp_out_view(0, 2) = 0.0;
387 DfDp_out_view(1, 0) = -(f / L) * (f / L);
388 DfDp_out_view(1, 1) = -(2.0 * f / (L * L)) * (a - x_in_view[0]);
389 DfDp_out_view(1, 2) = +(2.0 * f * f / (L * L * L)) * (a - x_in_view[0]);
392 if (useDfDpAsTangent_ && !
is_null(DxdotDp_in)) {
394 DfDp_out_view(0, 0) += DxdotDp(0, 0);
395 DfDp_out_view(0, 1) += DxdotDp(0, 1);
396 DfDp_out_view(0, 2) += DxdotDp(0, 2);
397 DfDp_out_view(1, 0) += DxdotDp(1, 0);
398 DfDp_out_view(1, 1) += DxdotDp(1, 1);
399 DfDp_out_view(1, 2) += DxdotDp(1, 2);
401 if (useDfDpAsTangent_ && !
is_null(DxDp_in)) {
403 DfDp_out_view(0, 0) += -DxDp(1, 0);
404 DfDp_out_view(0, 1) += -DxDp(1, 1);
405 DfDp_out_view(0, 2) += -DxDp(1, 2);
406 DfDp_out_view(1, 0) += (f / L) * (f / L) * DxDp(0, 0);
407 DfDp_out_view(1, 1) += (f / L) * (f / L) * DxDp(0, 1);
408 DfDp_out_view(1, 2) += (f / L) * (f / L) * DxDp(0, 2);
414 if (acceptModelParams_) {
416 if (g_out != Teuchos::null) Thyra::assign(g_out.
ptr(), *x_in);
419 outArgs.
get_DgDp(0, 0).getMultiVector();
420 if (DgDp_out != Teuchos::null) Thyra::assign(DgDp_out.ptr(), Scalar(0.0));
423 outArgs.
get_DgDx(0).getMultiVector();
424 if (DgDx_out != Teuchos::null) {
426 DgDx_out_view(0, 0) = 1.0;
427 DgDx_out_view(0, 1) = 0.0;
428 DgDx_out_view(1, 0) = 0.0;
429 DgDx_out_view(1, 1) = 1.0;
434 template <
class Scalar>
438 if (!acceptModelParams_) {
439 return Teuchos::null;
444 else if (l == 1 || l == 2)
446 return Teuchos::null;
449 template <
class Scalar>
453 if (!acceptModelParams_) {
454 return Teuchos::null;
460 p_strings->push_back(
"Model Coefficient: a");
461 p_strings->push_back(
"Model Coefficient: f");
462 p_strings->push_back(
"Model Coefficient: L");
465 p_strings->push_back(
"DxDp");
467 p_strings->push_back(
"Dx_dotDp");
471 template <
class Scalar>
481 template <
class Scalar>
484 if (isInitialized_) {
492 MEB::InArgsSetup<Scalar> inArgs;
493 inArgs.setModelEvalDescription(this->description());
494 inArgs.setSupports(MEB::IN_ARG_t);
495 inArgs.setSupports(MEB::IN_ARG_x);
496 inArgs.setSupports(MEB::IN_ARG_beta);
497 inArgs.setSupports(MEB::IN_ARG_x_dot);
498 inArgs.setSupports(MEB::IN_ARG_alpha);
499 if (acceptModelParams_) {
507 MEB::OutArgsSetup<Scalar> outArgs;
508 outArgs.setModelEvalDescription(this->description());
509 outArgs.setSupports(MEB::OUT_ARG_f);
510 outArgs.setSupports(MEB::OUT_ARG_W_op);
511 if (acceptModelParams_) {
512 outArgs.set_Np_Ng(Np_, Ng_);
513 outArgs.setSupports(MEB::OUT_ARG_DfDp, 0, MEB::DERIV_MV_JACOBIAN_FORM);
514 outArgs.setSupports(MEB::OUT_ARG_DgDp, 0, 0, MEB::DERIV_MV_JACOBIAN_FORM);
515 outArgs.setSupports(MEB::OUT_ARG_DgDx, 0, MEB::DERIV_MV_GRADIENT_FORM);
521 nominalValues_ = inArgs_;
523 nominalValues_.set_t(t0_ic_);
527 x_ic_view[0] = a_ + b_ * sin((f_ / L_) * t0_ic_ + phi_);
528 x_ic_view[1] = b_ * (f_ / L_) * cos((f_ / L_) * t0_ic_ + phi_);
530 nominalValues_.set_x(x_ic);
531 if (acceptModelParams_) {
539 nominalValues_.set_p(0, p_ic);
544 x_dot_ic_view[0] = b_ * (f_ / L_) * cos((f_ / L_) * t0_ic_ + phi_);
546 -b_ * (f_ / L_) * (f_ / L_) * sin((f_ / L_) * t0_ic_ + phi_);
548 nominalValues_.set_x_dot(x_dot_ic);
551 isInitialized_ =
true;
554 template <
class Scalar>
562 if (paramList != Teuchos::null) tmpPL = paramList;
564 this->setMyParamList(tmpPL);
566 bool acceptModelParams = get<bool>(*pl,
"Accept model parameters");
567 bool haveIC = get<bool>(*pl,
"Provide nominal values");
568 bool useDfDpAsTangent = get<bool>(*pl,
"Use DfDp as Tangent");
569 if ((acceptModelParams != acceptModelParams_) || (haveIC != haveIC_)) {
570 isInitialized_ =
false;
572 acceptModelParams_ = acceptModelParams;
574 useDfDpAsTangent_ = useDfDpAsTangent;
575 a_ = get<Scalar>(*pl,
"Coeff a");
576 f_ = get<Scalar>(*pl,
"Coeff f");
577 L_ = get<Scalar>(*pl,
"Coeff L");
578 x0_ic_ = get<Scalar>(*pl,
"IC x0");
579 x1_ic_ = get<Scalar>(*pl,
"IC x1");
580 t0_ic_ = get<Scalar>(*pl,
"IC t0");
581 calculateCoeffFromIC_();
585 template <
class Scalar>
592 pl->
set(
"Accept model parameters",
false);
593 pl->
set(
"Provide nominal values",
true);
594 pl->
set(
"Use DfDp as Tangent",
false);
595 pl->
set<std::string>(
"Output File Name",
"Tempus_BDF2_SinCos");
596 Teuchos::setDoubleParameter(
"Coeff a", 0.0,
"Coefficient a in model", &*pl);
597 Teuchos::setDoubleParameter(
"Coeff f", 1.0,
"Coefficient f in model", &*pl);
598 Teuchos::setDoubleParameter(
"Coeff L", 1.0,
"Coefficient L in model", &*pl);
599 Teuchos::setDoubleParameter(
"IC x0", 0.0,
"Initial Condition for x0", &*pl);
600 Teuchos::setDoubleParameter(
"IC x1", 1.0,
"Initial Condition for x1", &*pl);
601 Teuchos::setDoubleParameter(
"IC t0", 0.0,
"Initial time t0", &*pl);
602 Teuchos::setIntParameter(
"Number of Time Step Sizes", 1,
603 "Number time step sizes for convergence study",
610 template <
class Scalar>
613 phi_ = atan(((f_ / L_) / x1_ic_) * (x0_ic_ - a_)) - (f_ / L_) * t0_ic_;
614 b_ = x1_ic_ / ((f_ / L_) * cos((f_ / L_) * t0_ic_ + phi_));
617 template <
class Scalar>
623 this->get_W_factory();
641 V_V(multivec->col(0).
ptr(), *vec);
647 V_V(multivec->col(1).
ptr(), *vec);
651 Thyra::linearOpWithSolve<Scalar>(*W_factory, matrix);
655 template <
class Scalar>
660 Thyra::createMembers(this->f_space_, this->dim_);
664 template <
class Scalar>
675 inArgs.setModelEvalDescription(this->description());
679 template <
class Scalar>
684 MEB::OutArgsSetup<Scalar> outArgs;
685 outArgs.setModelEvalDescription(this->description());
688 outArgs.setSupports(MEB::OUT_ARG_W_op);
689 outArgs.set_Np_Ng(this->Np_, 0);
693 template <
class Scalar>
699 using Teuchos::rcp_dynamic_cast;
703 "Error, setupInOutArgs_ must be called first!\n");
712 if (this->acceptModelParams_) {
714 inArgs.
get_p(0).assert_not_null();
731 matrix_view(0, 0) = 0.0;
732 matrix_view(1, 0) = +beta;
733 matrix_view(0, 1) = -beta * (f / L) * (f / L);
734 matrix_view(1, 1) = 0.0;
741 x_dot_in = inArgs.
get_x_dot().assert_not_null();
748 matrix_view(0, 0) = alpha;
749 matrix_view(1, 0) = -beta;
750 matrix_view(0, 1) = +beta * (f / L) * (f / L);
751 matrix_view(1, 1) = alpha;
758 #endif // TEMPUS_TEST_SINCOS_MODEL_IMPL_HPP
bool is_null(const boost::shared_ptr< T > &p)
Derivative< Scalar > get_DfDp(int l) const
RCP< const VectorBase< Scalar > > get_x_dot() const
ParameterList & set(std::string const &name, T const &value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Thyra::ModelEvaluatorBase::InArgs< Scalar > createInArgs() const
Evaluation< VectorBase< Scalar > > get_g(int j) const
Evaluation< VectorBase< Scalar > > get_f() const
Teuchos::RCP< Thyra::LinearOpBase< Scalar > > create_W_op() const
Teuchos::RCP< Thyra::LinearOpWithSolveBase< Scalar > > create_W() const
Thyra::ModelEvaluatorBase::InArgs< Scalar > getNominalValues() const
Derivative< Scalar > get_DgDp(int j, int l) const
Teuchos::RCP< const Thyra::VectorSpaceBase< Scalar > > get_f_space() const
Teuchos::RCP< Thyra::LinearOpBase< Scalar > > create_W_op() const
#define TEUCHOS_ASSERT_IN_RANGE_UPPER_EXCLUSIVE(index, lower_inclusive, upper_exclusive)
void set_x(const RCP< const VectorBase< Scalar > > &x)
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
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
Thyra::ModelEvaluatorBase::InArgs< Scalar > createInArgs() const
Thyra::ModelEvaluatorBase::InArgs< Scalar > getExactSolution(double t) const
SinCosModel(Teuchos::RCP< Teuchos::ParameterList > pList=Teuchos::null)
void validateParametersAndSetDefaults(ParameterList const &validParamList, int const depth=1000)
Teuchos::RCP< const Thyra::VectorSpaceBase< Scalar > > get_p_space(int l) const
Thyra::ModelEvaluatorBase::OutArgs< Scalar > createOutArgsImpl() const
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const
void set_x_dot(const RCP< const VectorBase< Scalar > > &x_dot)
void evalModelImpl(const Thyra::ModelEvaluatorBase::InArgs< Scalar > &inArgs_bar, const Thyra::ModelEvaluatorBase::OutArgs< Scalar > &outArgs_bar) const
Teuchos::RCP< const Thyra::VectorSpaceBase< Scalar > > get_g_space(int j) const
void calculateCoeffFromIC_()
Teuchos::RCP< const Teuchos::Array< std::string > > get_p_names(int l) const
Thyra::ModelEvaluatorBase::OutArgs< Scalar > createOutArgsImpl() const
void setupInOutArgs_() const
Thyra::ModelEvaluatorBase::InArgs< Scalar > getExactSensSolution(int j, double t) const
Teuchos::RCP< const Thyra::LinearOpWithSolveFactoryBase< Scalar > > get_W_factory() const
RCP< LinearOpBase< Scalar > > get_W_op() const
RCP< const VectorBase< Scalar > > get_x() const
RCP< const VectorBase< Scalar > > get_p(int l) const
RCP< MultiVectorBase< Scalar > > getMultiVector() const
Teuchos::RCP< Thyra::LinearOpWithSolveBase< Scalar > > create_W() const
void setParameterList(Teuchos::RCP< Teuchos::ParameterList > const ¶mList)
Derivative< Scalar > get_DgDx(int j) const