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"
29 template<
class Scalar>
33 isInitialized_ =
false;
39 acceptModelParams_ =
false;
40 useDfDpAsTangent_ =
false;
50 x_space_ = Thyra::defaultSpmdVectorSpace<Scalar>(dim_);
51 f_space_ = Thyra::defaultSpmdVectorSpace<Scalar>(dim_);
53 p_space_ = Thyra::defaultSpmdVectorSpace<Scalar>(np_);
54 g_space_ = Thyra::defaultSpmdVectorSpace<Scalar>(ng_);
56 setParameterList(pList_);
59 DxDp_space_ = Thyra::multiVectorProductVectorSpace(x_space_, np_);
62 template<
class Scalar>
63 Thyra::ModelEvaluatorBase::InArgs<Scalar>
67 TEUCHOS_TEST_FOR_EXCEPTION( !isInitialized_, std::logic_error,
68 "Error, setupInOutArgs_ must be called first!\n");
69 Thyra::ModelEvaluatorBase::InArgs<Scalar> inArgs = inArgs_;
71 inArgs.set_t(exact_t);
72 Teuchos::RCP<Thyra::VectorBase<Scalar> > exact_x = createMember(x_space_);
74 Thyra::DetachedVectorView<Scalar> exact_x_view(*exact_x);
75 exact_x_view[0] = a_+b_*sin((f_/L_)*t+phi_);
76 exact_x_view[1] = b_*(f_/L_)*cos((f_/L_)*t+phi_);
78 inArgs.set_x(exact_x);
79 Teuchos::RCP<Thyra::VectorBase<Scalar> > exact_x_dot = createMember(x_space_);
81 Thyra::DetachedVectorView<Scalar> exact_x_dot_view(*exact_x_dot);
82 exact_x_dot_view[0] = b_*(f_/L_)*cos((f_/L_)*t+phi_);
83 exact_x_dot_view[1] = -b_*(f_/L_)*(f_/L_)*sin((f_/L_)*t+phi_);
85 inArgs.set_x_dot(exact_x_dot);
95 template<
class Scalar>
96 Thyra::ModelEvaluatorBase::InArgs<Scalar>
100 TEUCHOS_TEST_FOR_EXCEPTION( !isInitialized_, std::logic_error,
101 "Error, setupInOutArgs_ must be called first!\n");
102 Thyra::ModelEvaluatorBase::InArgs<Scalar> inArgs = inArgs_;
103 if (!acceptModelParams_) {
106 TEUCHOS_ASSERT_IN_RANGE_UPPER_EXCLUSIVE( j, 0, np_ );
112 inArgs.set_t(exact_t);
113 Teuchos::RCP<Thyra::VectorBase<Scalar> > exact_s = createMember(x_space_);
115 Thyra::DetachedVectorView<Scalar> exact_s_view(*exact_s);
117 exact_s_view[0] = 1.0;
118 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)-(b*f*t/(L*L))*sin((f/L)*t+phi);
123 exact_s_view[0] = -(b*f*t/(L*L))*cos((f/L)*t+phi);
124 exact_s_view[1] = -(b*f/(L*L))*cos((f/L)*t+phi)+(b*f*f*t/(L*L*L))*sin((f/L)*t+phi);
127 inArgs.set_x(exact_s);
128 Teuchos::RCP<Thyra::VectorBase<Scalar> > exact_s_dot = createMember(x_space_);
130 Thyra::DetachedVectorView<Scalar> exact_s_dot_view(*exact_s_dot);
132 exact_s_dot_view[0] = 0.0;
133 exact_s_dot_view[1] = 0.0;
135 exact_s_dot_view[0] = (b/L)*cos((f/L)*t+phi)-(b*f*t/(L*L))*sin((f/L)*t+phi);
136 exact_s_dot_view[1] = -(2.0*b*f/(L*L))*sin((f/L)*t+phi)-(b*f*f*t/(L*L*L))*cos((f/L)*t+phi);
138 exact_s_dot_view[0] = -(b*f/(L*L))*cos((f/L)*t+phi)+(b*f*f*t/(L*L*L))*sin((f/L)*t+phi);
139 exact_s_dot_view[1] = (2.0*b*f*f/(L*L*L))*sin((f/L)*t+phi)+(b*f*f*f*t/(L*L*L*L))*cos((f/L)*t+phi);
142 inArgs.set_x_dot(exact_s_dot);
146 template<
class Scalar>
147 Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar> >
155 template<
class Scalar>
156 Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar> >
164 template<
class Scalar>
165 Thyra::ModelEvaluatorBase::InArgs<Scalar>
169 TEUCHOS_TEST_FOR_EXCEPTION( !isInitialized_, std::logic_error,
170 "Error, setupInOutArgs_ must be called first!\n");
171 return nominalValues_;
175 template<
class Scalar>
176 Teuchos::RCP<Thyra::LinearOpWithSolveBase<Scalar> >
181 RCP<const Thyra::LinearOpWithSolveFactoryBase<Scalar> > W_factory = this->get_W_factory();
182 RCP<Thyra::LinearOpBase<Scalar> > matrix = this->create_W_op();
189 RCP<Thyra::MultiVectorBase<Scalar> > multivec = Teuchos::rcp_dynamic_cast<Thyra::MultiVectorBase<Scalar> >(matrix,
true);
191 RCP<Thyra::VectorBase<Scalar> > vec = Thyra::createMember(x_space_);
193 Thyra::DetachedVectorView<Scalar> vec_view( *vec );
197 V_V(multivec->col(0).ptr(),*vec);
199 Thyra::DetachedVectorView<Scalar> vec_view( *vec );
203 V_V(multivec->col(1).ptr(),*vec);
206 RCP<Thyra::LinearOpWithSolveBase<Scalar> > W =
207 Thyra::linearOpWithSolve<Scalar>(
221 template<
class Scalar>
222 Teuchos::RCP<Thyra::LinearOpBase<Scalar> >
226 Teuchos::RCP<Thyra::MultiVectorBase<Scalar> > matrix = Thyra::createMembers(x_space_, dim_);
231 template<
class Scalar>
232 Teuchos::RCP<const Thyra::LinearOpWithSolveFactoryBase<Scalar> >
236 Teuchos::RCP<Thyra::LinearOpWithSolveFactoryBase<Scalar> > W_factory =
237 Thyra::defaultSerialDenseLinearOpWithSolveFactory<Scalar>();
253 template<
class Scalar>
254 Thyra::ModelEvaluatorBase::InArgs<Scalar>
266 template<
class Scalar>
267 Thyra::ModelEvaluatorBase::OutArgs<Scalar>
276 template<
class Scalar>
280 const Thyra::ModelEvaluatorBase::InArgs<Scalar> &inArgs,
281 const Thyra::ModelEvaluatorBase::OutArgs<Scalar> &outArgs
284 typedef Thyra::DefaultMultiVectorProductVector<Scalar> DMVPV;
286 using Thyra::VectorBase;
287 using Thyra::MultiVectorBase;
288 using Teuchos::rcp_dynamic_cast;
289 TEUCHOS_TEST_FOR_EXCEPTION( !isInitialized_, std::logic_error,
290 "Error, setupInOutArgs_ must be called first!\n");
292 const RCP<const VectorBase<Scalar> > x_in = inArgs.get_x().assert_not_null();
293 Thyra::ConstDetachedVectorView<Scalar> x_in_view( *x_in );
299 if (acceptModelParams_) {
300 const RCP<const VectorBase<Scalar> > p_in =
301 inArgs.get_p(0).assert_not_null();
302 Thyra::ConstDetachedVectorView<Scalar> p_in_view( *p_in );
308 RCP<const MultiVectorBase<Scalar> > DxDp_in, DxdotDp_in;
309 if (acceptModelParams_) {
310 if (inArgs.get_p(1) != Teuchos::null)
312 rcp_dynamic_cast<const DMVPV>(inArgs.get_p(1))->getMultiVector();
313 if (inArgs.get_p(2) != Teuchos::null)
315 rcp_dynamic_cast<const DMVPV>(inArgs.get_p(2))->getMultiVector();
318 Scalar beta = inArgs.get_beta();
320 const RCP<VectorBase<Scalar> > f_out = outArgs.get_f();
321 const RCP<Thyra::LinearOpBase<Scalar> > W_out = outArgs.get_W_op();
322 RCP<Thyra::MultiVectorBase<Scalar> > DfDp_out;
323 if (acceptModelParams_) {
324 Thyra::ModelEvaluatorBase::Derivative<Scalar> DfDp = outArgs.get_DfDp(0);
325 DfDp_out = DfDp.getMultiVector();
328 if (inArgs.get_x_dot().is_null()) {
331 if (!is_null(f_out)) {
332 Thyra::DetachedVectorView<Scalar> f_out_view( *f_out );
333 f_out_view[0] = x_in_view[1];
334 f_out_view[1] = (f/L)*(f/L)*(a-x_in_view[0]);
336 if (!is_null(W_out)) {
337 RCP<Thyra::MultiVectorBase<Scalar> > matrix =
338 Teuchos::rcp_dynamic_cast<Thyra::MultiVectorBase<Scalar> >(W_out,
true);
339 Thyra::DetachedMultiVectorView<Scalar> matrix_view( *matrix );
340 matrix_view(0,0) = 0.0;
341 matrix_view(0,1) = +beta;
342 matrix_view(1,0) = -beta*(f/L)*(f/L);
343 matrix_view(1,1) = 0.0;
346 if (!is_null(DfDp_out)) {
347 Thyra::DetachedMultiVectorView<Scalar> DfDp_out_view( *DfDp_out );
348 DfDp_out_view(0,0) = 0.0;
349 DfDp_out_view(0,1) = 0.0;
350 DfDp_out_view(0,2) = 0.0;
351 DfDp_out_view(1,0) = (f/L)*(f/L);
352 DfDp_out_view(1,1) = (2.0*f/(L*L))*(a-x_in_view[0]);
353 DfDp_out_view(1,2) = -(2.0*f*f/(L*L*L))*(a-x_in_view[0]);
356 if (useDfDpAsTangent_ && !is_null(DxDp_in)) {
357 Thyra::ConstDetachedMultiVectorView<Scalar> DxDp( *DxDp_in );
358 DfDp_out_view(0,0) += DxDp(1,0);
359 DfDp_out_view(0,1) += DxDp(1,1);
360 DfDp_out_view(0,2) += DxDp(1,2);
361 DfDp_out_view(1,0) += -(f/L)*(f/L) * DxDp(0,0);
362 DfDp_out_view(1,1) += -(f/L)*(f/L) * DxDp(0,1);
363 DfDp_out_view(1,2) += -(f/L)*(f/L) * DxDp(0,2);
369 RCP<const VectorBase<Scalar> > x_dot_in;
370 x_dot_in = inArgs.get_x_dot().assert_not_null();
371 Scalar alpha = inArgs.get_alpha();
372 if (!is_null(f_out)) {
373 Thyra::DetachedVectorView<Scalar> f_out_view( *f_out );
374 Thyra::ConstDetachedVectorView<Scalar> x_dot_in_view( *x_dot_in );
375 f_out_view[0] = x_dot_in_view[0] - x_in_view[1];
376 f_out_view[1] = x_dot_in_view[1] - (f/L)*(f/L)*(a-x_in_view[0]);
378 if (!is_null(W_out)) {
379 RCP<Thyra::MultiVectorBase<Scalar> > matrix =
380 Teuchos::rcp_dynamic_cast<Thyra::MultiVectorBase<Scalar> >(W_out,
true);
381 Thyra::DetachedMultiVectorView<Scalar> matrix_view( *matrix );
382 matrix_view(0,0) = alpha;
383 matrix_view(0,1) = -beta;
384 matrix_view(1,0) = +beta*(f/L)*(f/L);
385 matrix_view(1,1) = alpha;
388 if (!is_null(DfDp_out)) {
389 Thyra::DetachedMultiVectorView<Scalar> DfDp_out_view( *DfDp_out );
390 DfDp_out_view(0,0) = 0.0;
391 DfDp_out_view(0,1) = 0.0;
392 DfDp_out_view(0,2) = 0.0;
393 DfDp_out_view(1,0) = -(f/L)*(f/L);
394 DfDp_out_view(1,1) = -(2.0*f/(L*L))*(a-x_in_view[0]);
395 DfDp_out_view(1,2) = +(2.0*f*f/(L*L*L))*(a-x_in_view[0]);
398 if (useDfDpAsTangent_ && !is_null(DxdotDp_in)) {
399 Thyra::ConstDetachedMultiVectorView<Scalar> DxdotDp( *DxdotDp_in );
400 DfDp_out_view(0,0) += DxdotDp(0,0);
401 DfDp_out_view(0,1) += DxdotDp(0,1);
402 DfDp_out_view(0,2) += DxdotDp(0,2);
403 DfDp_out_view(1,0) += DxdotDp(1,0);
404 DfDp_out_view(1,1) += DxdotDp(1,1);
405 DfDp_out_view(1,2) += DxdotDp(1,2);
407 if (useDfDpAsTangent_ && !is_null(DxDp_in)) {
408 Thyra::ConstDetachedMultiVectorView<Scalar> DxDp( *DxDp_in );
409 DfDp_out_view(0,0) += -DxDp(1,0);
410 DfDp_out_view(0,1) += -DxDp(1,1);
411 DfDp_out_view(0,2) += -DxDp(1,2);
412 DfDp_out_view(1,0) += (f/L)*(f/L) * DxDp(0,0);
413 DfDp_out_view(1,1) += (f/L)*(f/L) * DxDp(0,1);
414 DfDp_out_view(1,2) += (f/L)*(f/L) * DxDp(0,2);
420 if (acceptModelParams_) {
421 RCP<VectorBase<Scalar> > g_out = outArgs.get_g(0);
422 if (g_out != Teuchos::null)
423 Thyra::assign(g_out.ptr(), *x_in);
425 RCP<Thyra::MultiVectorBase<Scalar> > DgDp_out =
426 outArgs.get_DgDp(0,0).getMultiVector();
427 if (DgDp_out != Teuchos::null)
428 Thyra::assign(DgDp_out.ptr(), Scalar(0.0));
430 RCP<Thyra::MultiVectorBase<Scalar> > DgDx_out =
431 outArgs.get_DgDx(0).getMultiVector();
432 if (DgDx_out != Teuchos::null) {
433 Thyra::DetachedMultiVectorView<Scalar> DgDx_out_view( *DgDx_out );
434 DgDx_out_view(0,0) = 1.0;
435 DgDx_out_view(0,1) = 0.0;
436 DgDx_out_view(1,0) = 0.0;
437 DgDx_out_view(1,1) = 1.0;
442 template<
class Scalar>
443 Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar> >
447 if (!acceptModelParams_) {
448 return Teuchos::null;
450 TEUCHOS_ASSERT_IN_RANGE_UPPER_EXCLUSIVE( l, 0, Np_ );
453 else if (l == 1 || l == 2)
455 return Teuchos::null;
458 template<
class Scalar>
459 Teuchos::RCP<const Teuchos::Array<std::string> >
463 if (!acceptModelParams_) {
464 return Teuchos::null;
466 TEUCHOS_ASSERT_IN_RANGE_UPPER_EXCLUSIVE( l, 0, Np_ );
467 Teuchos::RCP<Teuchos::Array<std::string> > p_strings =
468 Teuchos::rcp(
new Teuchos::Array<std::string>());
470 p_strings->push_back(
"Model Coefficient: a");
471 p_strings->push_back(
"Model Coefficient: f");
472 p_strings->push_back(
"Model Coefficient: L");
475 p_strings->push_back(
"DxDp");
477 p_strings->push_back(
"Dx_dotDp");
481 template<
class Scalar>
482 Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar> >
486 TEUCHOS_ASSERT_IN_RANGE_UPPER_EXCLUSIVE( j, 0, Ng_ );
492 template<
class Scalar>
497 if (isInitialized_) {
503 Thyra::ModelEvaluatorBase::InArgsSetup<Scalar> inArgs;
504 inArgs.setModelEvalDescription(this->description());
505 inArgs.setSupports( Thyra::ModelEvaluatorBase::IN_ARG_t );
506 inArgs.setSupports( Thyra::ModelEvaluatorBase::IN_ARG_x );
507 inArgs.setSupports( Thyra::ModelEvaluatorBase::IN_ARG_beta );
508 inArgs.setSupports( Thyra::ModelEvaluatorBase::IN_ARG_x_dot );
509 inArgs.setSupports( Thyra::ModelEvaluatorBase::IN_ARG_alpha );
510 if (acceptModelParams_) {
518 Thyra::ModelEvaluatorBase::OutArgsSetup<Scalar> outArgs;
519 outArgs.setModelEvalDescription(this->description());
520 outArgs.setSupports( Thyra::ModelEvaluatorBase::OUT_ARG_f );
521 outArgs.setSupports( Thyra::ModelEvaluatorBase::OUT_ARG_W_op );
522 if (acceptModelParams_) {
523 outArgs.set_Np_Ng(Np_,Ng_);
524 outArgs.setSupports( Thyra::ModelEvaluatorBase::OUT_ARG_DfDp,0,
525 Thyra::ModelEvaluatorBase::DERIV_MV_BY_COL );
526 outArgs.setSupports( Thyra::ModelEvaluatorBase::OUT_ARG_DgDp,0,0,
527 Thyra::ModelEvaluatorBase::DERIV_MV_BY_COL );
528 outArgs.setSupports( Thyra::ModelEvaluatorBase::OUT_ARG_DgDx,0,
529 Thyra::ModelEvaluatorBase::DERIV_TRANS_MV_BY_ROW );
535 nominalValues_ = inArgs_;
538 nominalValues_.set_t(t0_ic_);
539 const Teuchos::RCP<Thyra::VectorBase<Scalar> > x_ic = createMember(x_space_);
541 Thyra::DetachedVectorView<Scalar> x_ic_view( *x_ic );
542 x_ic_view[0] = a_+b_*sin((f_/L_)*t0_ic_+phi_);
543 x_ic_view[1] = b_*(f_/L_)*cos((f_/L_)*t0_ic_+phi_);
545 nominalValues_.set_x(x_ic);
546 if (acceptModelParams_) {
547 const Teuchos::RCP<Thyra::VectorBase<Scalar> > p_ic = createMember(p_space_);
549 Thyra::DetachedVectorView<Scalar> p_ic_view( *p_ic );
554 nominalValues_.set_p(0,p_ic);
556 const Teuchos::RCP<Thyra::VectorBase<Scalar> > x_dot_ic = createMember(x_space_);
558 Thyra::DetachedVectorView<Scalar> x_dot_ic_view( *x_dot_ic );
559 x_dot_ic_view[0] = b_*(f_/L_)*cos((f_/L_)*t0_ic_+phi_);
560 x_dot_ic_view[1] = -b_*(f_/L_)*(f_/L_)*sin((f_/L_)*t0_ic_+phi_);
562 nominalValues_.set_x_dot(x_dot_ic);
565 isInitialized_ =
true;
569 template<
class Scalar>
575 using Teuchos::ParameterList;
576 Teuchos::RCP<ParameterList> tmpPL = Teuchos::rcp(
new ParameterList(
"SinCosModel"));
577 if (paramList != Teuchos::null) tmpPL = paramList;
578 tmpPL->validateParametersAndSetDefaults(*this->getValidParameters());
579 this->setMyParamList(tmpPL);
580 Teuchos::RCP<ParameterList> pl = this->getMyNonconstParamList();
581 bool acceptModelParams = get<bool>(*pl,
"Accept model parameters");
582 bool haveIC = get<bool>(*pl,
"Provide nominal values");
583 bool useDfDpAsTangent = get<bool>(*pl,
"Use DfDp as Tangent");
584 if ( (acceptModelParams != acceptModelParams_) ||
587 isInitialized_ =
false;
589 acceptModelParams_ = acceptModelParams;
591 useDfDpAsTangent_ = useDfDpAsTangent;
592 a_ = get<Scalar>(*pl,
"Coeff a");
593 f_ = get<Scalar>(*pl,
"Coeff f");
594 L_ = get<Scalar>(*pl,
"Coeff L");
595 x0_ic_ = get<Scalar>(*pl,
"IC x0");
596 x1_ic_ = get<Scalar>(*pl,
"IC x1");
597 t0_ic_ = get<Scalar>(*pl,
"IC t0");
598 calculateCoeffFromIC_();
602 template<
class Scalar>
603 Teuchos::RCP<const Teuchos::ParameterList>
607 static Teuchos::RCP<const Teuchos::ParameterList> validPL;
608 if (is_null(validPL)) {
609 Teuchos::RCP<Teuchos::ParameterList> pl = Teuchos::parameterList();
610 pl->set(
"Accept model parameters",
false);
611 pl->set(
"Provide nominal values",
true);
612 pl->set(
"Use DfDp as Tangent",
false);
613 pl->set<std::string>(
"Output File Name",
"Tempus_BDF2_SinCos");
614 Teuchos::setDoubleParameter(
615 "Coeff a", 0.0,
"Coefficient a in model", &*pl);
616 Teuchos::setDoubleParameter(
617 "Coeff f", 1.0,
"Coefficient f in model", &*pl);
618 Teuchos::setDoubleParameter(
619 "Coeff L", 1.0,
"Coefficient L in model", &*pl);
620 Teuchos::setDoubleParameter(
621 "IC x0", 0.0,
"Initial Condition for x0", &*pl);
622 Teuchos::setDoubleParameter(
623 "IC x1", 1.0,
"Initial Condition for x1", &*pl);
624 Teuchos::setDoubleParameter(
625 "IC t0", 0.0,
"Initial time t0", &*pl);
626 Teuchos::setIntParameter(
627 "Number of Time Step Sizes", 1,
"Number time step sizes for convergence study", &*pl);
633 template<
class Scalar>
638 phi_ = atan(((f_/L_)/x1_ic_)*(x0_ic_-a_))-(f_/L_)*t0_ic_;
639 b_ = x1_ic_/((f_/L_)*cos((f_/L_)*t0_ic_+phi_));
643 #endif // TEMPUS_TEST_SINCOS_MODEL_IMPL_HPP