155 const Thyra::ModelEvaluatorBase::InArgs<Scalar> &inArgs,
156 const Thyra::ModelEvaluatorBase::OutArgs<Scalar> &outArgs)
const
158 typedef Thyra::DefaultMultiVectorProductVector<Scalar> DMVPV;
160 using Teuchos::rcp_dynamic_cast;
161 TEUCHOS_TEST_FOR_EXCEPTION(!isInitialized_, std::logic_error,
162 "Error, setupInOutArgs_ must be called first!\n");
164 const RCP<const Thyra::VectorBase<Scalar> > x_in =
165 inArgs.get_x().assert_not_null();
166 Thyra::ConstDetachedVectorView<Scalar> x_in_view(*x_in);
167 Scalar x1 = x_in_view[0];
170 Scalar beta = inArgs.get_beta();
171 Scalar eps = epsilon_;
173 const RCP<const Thyra::VectorBase<Scalar> > p_in = inArgs.get_p(0);
174 if (p_in != Teuchos::null) {
175 Thyra::ConstDetachedVectorView<Scalar> p_in_view(*p_in);
179 RCP<const Thyra::MultiVectorBase<Scalar> > dxdp_in, dxdotdp_in, dydp_in;
180 if (inArgs.get_p(1) != Teuchos::null) {
182 rcp_dynamic_cast<const DMVPV>(inArgs.get_p(1),
true)->getMultiVector();
184 if (inArgs.get_p(2) != Teuchos::null) {
186 rcp_dynamic_cast<const DMVPV>(inArgs.get_p(2),
true)->getMultiVector();
188 if (inArgs.get_p(3) != Teuchos::null) {
190 rcp_dynamic_cast<const DMVPV>(inArgs.get_p(3),
true)->getMultiVector();
193 const RCP<const Thyra::VectorBase<Scalar> > y_in =
194 inArgs.get_p(4).assert_not_null();
195 Thyra::ConstDetachedVectorView<Scalar> y_in_view(*y_in);
196 Scalar x0 = y_in_view[0];
198 const RCP<Thyra::VectorBase<Scalar> > f_out = outArgs.get_f();
199 const RCP<Thyra::LinearOpBase<Scalar> > W_out = outArgs.get_W_op();
200 const RCP<Thyra::MultiVectorBase<Scalar> > DfDp_out =
201 outArgs.get_DfDp(0).getMultiVector();
202 const RCP<Thyra::MultiVectorBase<Scalar> > DfDx0_out =
203 outArgs.get_DfDp(4).getMultiVector();
205 if (inArgs.get_x_dot().is_null()) {
207 if (!is_null(f_out)) {
208 Thyra::DetachedVectorView<Scalar> f_out_view(*f_out);
209 f_out_view[0] = (1.0 - x0 * x0) * x1 / eps;
211 if (!is_null(DfDp_out)) {
212 Thyra::DetachedMultiVectorView<Scalar> DfDp_out_view(*DfDp_out);
213 DfDp_out_view(0, 0) = -(1.0 - x0 * x0) * x1 / (eps * eps);
216 if (useDfDpAsTangent_ && !is_null(dxdp_in)) {
217 Thyra::ConstDetachedMultiVectorView<Scalar> dxdp(*dxdp_in);
218 DfDp_out_view(0, 0) += (1.0 - x0 * x0) / eps * dxdp(0, 0);
220 if (useDfDpAsTangent_ && !is_null(dydp_in)) {
221 Thyra::ConstDetachedMultiVectorView<Scalar> dydp(*dydp_in);
222 DfDp_out_view(0, 0) += -2.0 * x0 * x1 / eps * dydp(0, 0);
225 if (!is_null(DfDx0_out)) {
226 Thyra::DetachedMultiVectorView<Scalar> DfDx0_out_view(*DfDx0_out);
227 DfDx0_out_view(0, 0) = -2.0 * x0 * x1 / eps;
229 if (!is_null(W_out)) {
230 RCP<Thyra::MultiVectorBase<Scalar> > W =
231 Teuchos::rcp_dynamic_cast<Thyra::MultiVectorBase<Scalar> >(W_out,
233 Thyra::DetachedMultiVectorView<Scalar> W_view(*W);
234 W_view(0, 0) = beta * (1.0 - x0 * x0) / eps;
240 RCP<const Thyra::VectorBase<Scalar> > x_dot_in;
241 x_dot_in = inArgs.get_x_dot().assert_not_null();
242 if (!is_null(f_out)) {
243 Thyra::DetachedVectorView<Scalar> f_out_view(*f_out);
244 Thyra::ConstDetachedVectorView<Scalar> x_dot_in_view(*x_dot_in);
245 f_out_view[0] = x_dot_in_view[0] - (1.0 - x0 * x0) * x1 / eps;
247 if (!is_null(DfDp_out)) {
248 Thyra::DetachedMultiVectorView<Scalar> DfDp_out_view(*DfDp_out);
249 DfDp_out_view(0, 0) = (1.0 - x0 * x0) * x1 / (eps * eps);
253 if (useDfDpAsTangent_ && !is_null(dxdotdp_in)) {
254 Thyra::ConstDetachedMultiVectorView<Scalar> dxdotdp(*dxdotdp_in);
255 DfDp_out_view(0, 0) += dxdotdp(0, 0);
257 if (useDfDpAsTangent_ && !is_null(dxdp_in)) {
258 Thyra::ConstDetachedMultiVectorView<Scalar> dxdp(*dxdp_in);
259 DfDp_out_view(0, 0) += -(1.0 - x0 * x0) / eps * dxdp(0, 0);
261 if (useDfDpAsTangent_ && !is_null(dydp_in)) {
262 Thyra::ConstDetachedMultiVectorView<Scalar> dydp(*dydp_in);
263 DfDp_out_view(0, 0) += 2.0 * x0 * x1 / eps * dydp(0, 0);
266 if (!is_null(DfDx0_out)) {
267 Thyra::DetachedMultiVectorView<Scalar> DfDx0_out_view(*DfDx0_out);
268 DfDx0_out_view(0, 0) = 2.0 * x0 * x1 / eps;
270 if (!is_null(W_out)) {
271 Scalar alpha = inArgs.get_alpha();
272 RCP<Thyra::MultiVectorBase<Scalar> > W =
273 Teuchos::rcp_dynamic_cast<Thyra::MultiVectorBase<Scalar> >(W_out,
275 Thyra::DetachedMultiVectorView<Scalar> W_view(*W);
276 W_view(0, 0) = alpha - beta * (1.0 - x0 * x0) / eps;
329 if (isInitialized_)
return;
333 Thyra::ModelEvaluatorBase::InArgsSetup<Scalar> inArgs;
334 inArgs.setModelEvalDescription(this->description());
335 inArgs.setSupports(Thyra::ModelEvaluatorBase::IN_ARG_x_dot);
336 inArgs.setSupports(Thyra::ModelEvaluatorBase::IN_ARG_x);
337 inArgs.setSupports(Thyra::ModelEvaluatorBase::IN_ARG_t);
338 inArgs.setSupports(Thyra::ModelEvaluatorBase::IN_ARG_alpha);
339 inArgs.setSupports(Thyra::ModelEvaluatorBase::IN_ARG_beta);
346 Thyra::ModelEvaluatorBase::OutArgsSetup<Scalar> outArgs;
347 outArgs.setModelEvalDescription(this->description());
348 outArgs.setSupports(Thyra::ModelEvaluatorBase::OUT_ARG_f);
349 outArgs.setSupports(Thyra::ModelEvaluatorBase::OUT_ARG_W_op);
350 outArgs.set_Np_Ng(Np_, Ng_);
351 outArgs.setSupports(Thyra::ModelEvaluatorBase::OUT_ARG_DfDp, 0,
352 Thyra::ModelEvaluatorBase::DERIV_MV_JACOBIAN_FORM);
353 outArgs.setSupports(Thyra::ModelEvaluatorBase::OUT_ARG_DfDp, 4,
354 Thyra::ModelEvaluatorBase::DERIV_MV_JACOBIAN_FORM);
359 nominalValues_ = inArgs_;
362 nominalValues_.set_t(t0_ic_);
363 const RCP<Thyra::VectorBase<Scalar> > x_ic = createMember(x_space_);
365 Thyra::DetachedVectorView<Scalar> x_ic_view(*x_ic);
366 x_ic_view[0] = x1_ic_;
368 nominalValues_.set_x(x_ic);
370 const RCP<Thyra::VectorBase<Scalar> > p_ic = createMember(p_space_);
371 const RCP<Thyra::VectorBase<Scalar> > y_ic = createMember(y_space_);
373 Thyra::DetachedVectorView<Scalar> p_ic_view(*p_ic);
374 Thyra::DetachedVectorView<Scalar> y_ic_view(*y_ic);
375 p_ic_view[0] = epsilon_;
376 y_ic_view[0] = x0_ic_;
378 nominalValues_.set_p(0, p_ic);
379 nominalValues_.set_p(4, y_ic);
381 const RCP<Thyra::VectorBase<Scalar> > x_dot_ic = createMember(x_space_);
383 Thyra::DetachedVectorView<Scalar> x_dot_ic_view(*x_dot_ic);
384 x_dot_ic_view[0] = ((1.0 - x0_ic_ * x0_ic_) * x1_ic_ - x0_ic_) / epsilon_;
386 nominalValues_.set_x_dot(x_dot_ic);
389 isInitialized_ =
true;
394 Teuchos::RCP<Teuchos::ParameterList>
const ¶mList)
397 using Teuchos::ParameterList;
398 Teuchos::RCP<ParameterList> tmpPL =
399 Teuchos::rcp(
new ParameterList(
"VanDerPol_IMEXPart_ImplicitModel"));
400 if (paramList != Teuchos::null) tmpPL = paramList;
401 tmpPL->validateParametersAndSetDefaults(*this->getValidParameters());
402 this->setMyParamList(tmpPL);
403 Teuchos::RCP<ParameterList> pl = this->getMyNonconstParamList();
404 bool haveIC = get<bool>(*pl,
"Provide nominal values");
405 bool useDfDpAsTangent = get<bool>(*pl,
"Use DfDp as Tangent");
406 if (haveIC != haveIC_) isInitialized_ =
false;
408 useDfDpAsTangent_ = useDfDpAsTangent;
409 epsilon_ = get<Scalar>(*pl,
"Coeff epsilon");
410 x0_ic_ = get<Scalar>(*pl,
"IC x0");
411 x1_ic_ = get<Scalar>(*pl,
"IC x1");
412 t0_ic_ = get<Scalar>(*pl,
"IC t0");