87 RCP<const Thyra::LinearOpWithSolveFactoryBase<Scalar> > W_factory =
88 this->get_W_factory();
89 RCP<Thyra::LinearOpBase<Scalar> > matrix = this->create_W_op();
96 RCP<Thyra::MultiVectorBase<Scalar> > multivec =
97 Teuchos::rcp_dynamic_cast<Thyra::MultiVectorBase<Scalar> >(matrix,
100 RCP<Thyra::VectorBase<Scalar> > vec = Thyra::createMember(x_space_);
102 Thyra::DetachedVectorView<Scalar> vec_view(*vec);
106 V_V(multivec->col(0).ptr(), *vec);
108 Thyra::DetachedVectorView<Scalar> vec_view(*vec);
112 V_V(multivec->col(1).ptr(), *vec);
115 RCP<Thyra::LinearOpWithSolveBase<Scalar> > W =
116 Thyra::linearOpWithSolve<Scalar>(*W_factory, matrix);
159 const Thyra::ModelEvaluatorBase::InArgs<Scalar> &inArgs,
160 const Thyra::ModelEvaluatorBase::OutArgs<Scalar> &outArgs)
const
162 typedef Thyra::DefaultMultiVectorProductVector<Scalar> DMVPV;
164 using Teuchos::rcp_dynamic_cast;
165 TEUCHOS_TEST_FOR_EXCEPTION(!isInitialized_, std::logic_error,
166 "Error, setupInOutArgs_ must be called first!\n");
168 const RCP<const Thyra::VectorBase<Scalar> > x_in =
169 inArgs.get_x().assert_not_null();
170 Thyra::ConstDetachedVectorView<Scalar> x_in_view(*x_in);
173 Scalar beta = inArgs.get_beta();
174 Scalar eps = epsilon_;
175 RCP<const Thyra::MultiVectorBase<Scalar> > dxdp_in, dxdotdp_in;
176 if (acceptModelParams_) {
177 const RCP<const Thyra::VectorBase<Scalar> > p_in = inArgs.get_p(0);
178 if (p_in != Teuchos::null) {
179 Thyra::ConstDetachedVectorView<Scalar> p_in_view(*p_in);
182 if (inArgs.get_p(1) != Teuchos::null) {
183 dxdp_in = rcp_dynamic_cast<const DMVPV>(inArgs.get_p(1),
true)
186 if (inArgs.get_p(2) != Teuchos::null) {
187 dxdotdp_in = rcp_dynamic_cast<const DMVPV>(inArgs.get_p(2),
true)
192 const RCP<Thyra::VectorBase<Scalar> > f_out = outArgs.get_f();
193 const RCP<Thyra::LinearOpBase<Scalar> > W_out = outArgs.get_W_op();
194 RCP<Thyra::MultiVectorBase<Scalar> > DfDp_out;
195 if (acceptModelParams_) {
196 Thyra::ModelEvaluatorBase::Derivative<Scalar> DfDp = outArgs.get_DfDp(0);
197 DfDp_out = DfDp.getMultiVector();
200 if (inArgs.get_x_dot().is_null()) {
202 if (!is_null(f_out)) {
203 Thyra::DetachedVectorView<Scalar> f_out_view(*f_out);
205 f_out_view[1] = (1.0 - x_in_view[0] * x_in_view[0]) * x_in_view[1] / eps;
207 if (!is_null(DfDp_out)) {
208 Thyra::DetachedMultiVectorView<Scalar> DfDp_out_view(*DfDp_out);
209 DfDp_out_view(0, 0) = 0.0;
210 DfDp_out_view(1, 0) =
211 -(1.0 - x_in_view[0] * x_in_view[0]) * x_in_view[1] / (eps * eps);
214 if (useDfDpAsTangent_ && !is_null(dxdp_in)) {
215 Thyra::ConstDetachedMultiVectorView<Scalar> dxdp(*dxdp_in);
216 DfDp_out_view(1, 0) +=
217 -2.0 * x_in_view[0] * x_in_view[1] / eps * dxdp(0, 0) +
218 (1.0 - x_in_view[0] * x_in_view[0]) / eps * dxdp(1, 0);
221 if (!is_null(W_out)) {
222 RCP<Thyra::MultiVectorBase<Scalar> > W =
223 Teuchos::rcp_dynamic_cast<Thyra::MultiVectorBase<Scalar> >(W_out,
225 Thyra::DetachedMultiVectorView<Scalar> W_view(*W);
229 -2.0 * beta * x_in_view[0] * x_in_view[1] / eps;
231 beta * (1.0 - x_in_view[0] * x_in_view[0]) / eps;
237 RCP<const Thyra::VectorBase<Scalar> > x_dot_in;
238 x_dot_in = inArgs.get_x_dot().assert_not_null();
239 Scalar alpha = inArgs.get_alpha();
241 if (!is_null(f_out)) {
242 Thyra::DetachedVectorView<Scalar> f_out_view(*f_out);
243 Thyra::ConstDetachedVectorView<Scalar> x_dot_in_view(*x_dot_in);
244 f_out_view[0] = x_dot_in_view[0];
245 f_out_view[1] = x_dot_in_view[1] -
246 (1.0 - x_in_view[0] * x_in_view[0]) * x_in_view[1] / eps;
248 if (!is_null(DfDp_out)) {
249 Thyra::DetachedMultiVectorView<Scalar> DfDp_out_view(*DfDp_out);
250 DfDp_out_view(0, 0) = 0.0;
251 DfDp_out_view(1, 0) =
252 (1.0 - x_in_view[0] * x_in_view[0]) * x_in_view[1] / (eps * eps);
255 if (useDfDpAsTangent_ && !is_null(dxdotdp_in)) {
256 Thyra::ConstDetachedMultiVectorView<Scalar> dxdotdp(*dxdotdp_in);
257 DfDp_out_view(0, 0) += dxdotdp(0, 0);
258 DfDp_out_view(1, 0) += dxdotdp(1, 0);
260 if (useDfDpAsTangent_ && !is_null(dxdp_in)) {
261 Thyra::ConstDetachedMultiVectorView<Scalar> dxdp(*dxdp_in);
262 DfDp_out_view(1, 0) +=
263 2.0 * x_in_view[0] * x_in_view[1] / eps * dxdp(0, 0) -
264 (1.0 - x_in_view[0] * x_in_view[0]) / eps * dxdp(1, 0);
267 if (!is_null(W_out)) {
268 RCP<Thyra::MultiVectorBase<Scalar> > W =
269 Teuchos::rcp_dynamic_cast<Thyra::MultiVectorBase<Scalar> >(W_out,
271 Thyra::DetachedMultiVectorView<Scalar> W_view(*W);
272 W_view(0, 0) = alpha;
275 2.0 * beta * x_in_view[0] * x_in_view[1] / eps;
276 W_view(1, 1) = alpha - beta * (1.0 - x_in_view[0] * x_in_view[0]) /
329 if (isInitialized_) {
335 Thyra::ModelEvaluatorBase::InArgsSetup<Scalar> inArgs;
336 inArgs.setModelEvalDescription(this->description());
337 inArgs.setSupports(Thyra::ModelEvaluatorBase::IN_ARG_x_dot);
338 inArgs.setSupports(Thyra::ModelEvaluatorBase::IN_ARG_x);
339 inArgs.setSupports(Thyra::ModelEvaluatorBase::IN_ARG_t);
340 inArgs.setSupports(Thyra::ModelEvaluatorBase::IN_ARG_alpha);
341 inArgs.setSupports(Thyra::ModelEvaluatorBase::IN_ARG_beta);
342 if (acceptModelParams_) {
350 Thyra::ModelEvaluatorBase::OutArgsSetup<Scalar> outArgs;
351 outArgs.setModelEvalDescription(this->description());
352 outArgs.setSupports(Thyra::ModelEvaluatorBase::OUT_ARG_f);
353 outArgs.setSupports(Thyra::ModelEvaluatorBase::OUT_ARG_W_op);
354 if (acceptModelParams_) {
355 outArgs.set_Np_Ng(Np_, Ng_);
356 outArgs.setSupports(Thyra::ModelEvaluatorBase::OUT_ARG_DfDp, 0,
357 Thyra::ModelEvaluatorBase::DERIV_MV_JACOBIAN_FORM);
363 nominalValues_ = inArgs_;
365 nominalValues_.set_t(t0_ic_);
366 const Teuchos::RCP<Thyra::VectorBase<Scalar> > x_ic =
367 createMember(x_space_);
369 Thyra::DetachedVectorView<Scalar> x_ic_view(*x_ic);
370 x_ic_view[0] = x0_ic_;
371 x_ic_view[1] = x1_ic_;
373 nominalValues_.set_x(x_ic);
374 if (acceptModelParams_) {
375 const Teuchos::RCP<Thyra::VectorBase<Scalar> > p_ic =
376 createMember(p_space_);
378 Thyra::DetachedVectorView<Scalar> p_ic_view(*p_ic);
379 p_ic_view[0] = epsilon_;
381 nominalValues_.set_p(0, p_ic);
383 const Teuchos::RCP<Thyra::VectorBase<Scalar> > x_dot_ic =
384 createMember(x_space_);
386 Thyra::DetachedVectorView<Scalar> x_dot_ic_view(*x_dot_ic);
387 x_dot_ic_view[0] = x1_ic_;
388 x_dot_ic_view[1] = ((1.0 - x0_ic_ * x0_ic_) * x1_ic_ - x0_ic_) / epsilon_;
390 nominalValues_.set_x_dot(x_dot_ic);
393 isInitialized_ =
true;
398 Teuchos::RCP<Teuchos::ParameterList>
const ¶mList)
401 using Teuchos::ParameterList;
402 Teuchos::RCP<ParameterList> tmpPL =
403 Teuchos::rcp(
new ParameterList(
"VanDerPol_IMEX_ImplicitModel"));
404 if (paramList != Teuchos::null) tmpPL = paramList;
405 tmpPL->validateParametersAndSetDefaults(*this->getValidParameters());
406 this->setMyParamList(tmpPL);
407 Teuchos::RCP<ParameterList> pl = this->getMyNonconstParamList();
408 bool acceptModelParams = get<bool>(*pl,
"Accept model parameters");
409 bool haveIC = get<bool>(*pl,
"Provide nominal values");
410 bool useDfDpAsTangent = get<bool>(*pl,
"Use DfDp as Tangent");
411 if ((acceptModelParams != acceptModelParams_) || (haveIC != haveIC_)) {
412 isInitialized_ =
false;
414 acceptModelParams_ = acceptModelParams;
416 useDfDpAsTangent_ = useDfDpAsTangent;
417 epsilon_ = get<Scalar>(*pl,
"Coeff epsilon");
418 x0_ic_ = get<Scalar>(*pl,
"IC x0");
419 x1_ic_ = get<Scalar>(*pl,
"IC x1");
420 t0_ic_ = get<Scalar>(*pl,
"IC t0");